Skip to main content

DjangoRestFramework API checker

Project description

DRF API Checker

pypi-version travis-png-m rtd-badge codecov-badge

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 check)
  • Response headers change (optional check)

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']`

How To use it:

unittest

Using 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)

Using ApiCheckerBase metaclass

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(),
           }

ApiCheckerBase can produce API test with minimum effort but it offers less flexibility than ApiCheckerMixin.

pytest

pytest integration is provided by two helpers frozenfixture and contract::

from django.urls import reverse
from drf_api_checker.pytest import contract, frozenfixture


@frozenfixture()
def frozen_detail(db):
    from demo.factories import DetailFactory
    return DetailFactory()

@contract()
def test_url(frozen_detail):
    url = reverse("master-list")
    return url

Custom checks:

Sometimes it is not possible to check a field by value but exists anyway a mechanism to check the contract (ie. timestamp field - ignore for this example tools like freezegun)

To handle this situations you can write custom Recorder with specia asserters:

from drf_api_checker.recorder import Recorder

class TimestampRecorder(Recorder):

    def assert_last_modify_date(self, response: Response, stored: Response, path: str):
        value = response['last_modify_date']
        assert datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%fZ')

custom asserter is a method named assert_<field_name>, in case of nested serializers you can have more specific asserter using assert_<fk_field_name>_<field_name>

Links

Develop travis-png-d
Master travis-png-m
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/
Documentation: https://drf-api-checker.readthedocs.org/en/develop/

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

drf-api-checker-0.8.1.tar.gz (16.4 kB view details)

Uploaded Source

File details

Details for the file drf-api-checker-0.8.1.tar.gz.

File metadata

  • Download URL: drf-api-checker-0.8.1.tar.gz
  • Upload date:
  • Size: 16.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/2.0.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.6.0 requests-toolbelt/0.9.1 tqdm/4.37.0 CPython/3.6.8

File hashes

Hashes for drf-api-checker-0.8.1.tar.gz
Algorithm Hash digest
SHA256 9d0e48966b7a04abd1377b9843e0e3cdd995814c585da2019355c43304d3f4d5
MD5 84c129396528b74a897e5ee228e1001a
BLAKE2b-256 614d39bf2311dfe3d2ee27c452b79c789f47906d6ce7fbceced3f6de3e3b0ddd

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page