DjangoRestFramework API checker¶
Overview¶
This module offers some utilities to avoid unwanted changes in Django Rest Framework responses, so to keep stable contracts
The purpose is to guarantee that any code changes never introduce ‘contract violations’ changing the Serialization behaviour.
Contract violations can happen when:
- fields are removed from Serializer
- field representation changes (ie. date/number format, )
- Response status code changes (optional)
- Response headers change (optional)
How it works:¶
First time the test run, the response and model instances are serialized and saved on the disk; any further execution is checked against this first response.
Test data are saved in the same directory where the test module lives,
under _api_checker/<module_fqn>/<test_class>
Fields that cannot be checked by value (ie timestamps/last modified) can be tested writing
custom assert_<field_name>
methods.
In case of nested objects, method names must follow the field “path”.
(ie. assert_permission_modified
vs assert_modified
)
This module can also intercept when a field is added,
in this case it is mandatory recreate stored test data; simply delete them from the disk
or set API_CHECKER_RESET
environment variable and run the test again,
In case something goes wrong the output will be
Field values mismatch
AssertionError: View `<class 'path.to.module.CustomerListAPIView>` breaks the contract.
Field `name` does not match.
- expected: `Partner 0`
- received: `Partner 11`
Field removed
AssertionError: View `<class 'path.to.module.CustomerListAPIView'>` breaks the contract.
Field `id` is missing in the new response
Field added
AssertionError: View `<class 'path.to.module.CustomerListAPIView'>` returned more field than expected.
Action needed api_customers.response.json need rebuild.
New fields are:
`['country']`
Table Of Contents¶
Install¶
Using pip
:
pip install drf-api-checker
Go to https://github.com/saxix/drf-api-checker if you need to download a package or clone the repo.
drf-api-checker does not need to be added into ``INSTALLED_APPS`
How to run the tests¶
$ pip install tox
$ tox
HowTo¶
ApiCheckerMixin¶
class TestAPIAgreements(ApiCheckerMixin, TestCase):
def get_fixtures(self):
return {'customer': CustomerFactory()}
def test_customer_detail(self):
url = reverse("customer-detail", args=[self.get_fixture('customer').pk])
self.assertGET(url)
ApiCheckerBase¶
class TestAPIIntervention(TestCase, metaclass=ApiCheckerBase):
URLS = [
reverse("intervention-list"),
reverse("intervention-detail", args=[101]),
]
def get_fixtures(cls):
return {'intervention': InterventionFactory(id=101),
'result': ResultFactory(),
}
Common Recipes¶
Check DateTimeField()
with auto_now=True
¶
Using Django TestCase:
Add a method assert_<fieldname>
that check by format instead
class TestUrls(TestCase, metaclass=ApiCheckerBase):
def assert_timestamp(self, response, expected, path=''):
value = response['timestamp']
assert datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%f')
With pytest:
Create a custom Recorder and pass it to @contract
from drf_api_checker.recorder import Recorder
from drf_api_checker.pytest import contract, frozenfixture
class MyRecorder(Recorder):
def assert_timestamp(self, response, expected, path=''):
value = response['timestamp']
assert datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%f')
@contract(recorder_class=MyRecorder)
def test_user_list(user):
return reverse('api:user-list')
Check protected url¶
Using Django TestCase:
Using standard DRF way: self.client.login()
or self.client.force_authenticate()
With pytest:
Create a custom Recorder and override client
property
class MyRecorder(Recorder):
@property
def client(self):
user = UserFactory(is_superuser=True)
client = APIClient()
client.force_authenticate(user)
return client
@contract(recorder_class=MyRecorder)
def test_user_list(user):
return reverse('api:user-list')
Check methods other than GET¶
from drf_api_checker.recorder import Recorder
from drf_api_checker.pytest import contract, frozenfixture
Links¶
- Project home page: https://github.com/saxix/drf-api-checker
- Issue tracker: https://github.com/saxix/drf-api-checker/issues?sort
- Download: http://pypi.python.org/pypi/drf-api-checker/
- Docs: http://readthedocs.org/docs/drf-api-checker/en/latest/
\ Sort by:\ best rated\ newest\ oldest\
\\
Add a comment\ (markup):
\``code``
, \ code blocks:::
and an indented block after blank line