Using Gabbi and Hypothesis to Test Django APIs

In the world of testing it is important to write tests that are both easy to read and covering a wide range of scenarios. Often one of these will be sacrificed to facilitate the other, such as hard coding your examples so that your test logic remains clear or by creating an overly complicated setup so that multiple scenarios can be explored. Here we discuss two tools that, when combined, will allow you to explore more of the test surface of your web API while still creating clear and maintainable tests.

Hypothesis

Hypothesis is a library that, when provided with a description of the parameters for your API will explore many situations that will stress your system. Hypothesis uses "strategies" to inject parameters into your test cases.

from hypothesis import given
from hypothesis.strategies import floats
from my.module import add

@given(floats(), floats())
def test_float_addition_is_commutative(first, second):
    assert add(first, second) == add(second, first)

Gabbi

Gabbi is a tool for declaratively creating tests for web APIs using YAML files to declare the test API calls and expected responses.

tests:
 - name: create thing
   url: /app/api/things/
   method: POST
   status: 201
   request_headers:
     content-type: application/json
   data:
     name: my things name

Combining The Two

By creating a custom test case inheriting from both Hypothesis and Gabbi, we can pass randomized data from Hypothesis directly into our declaratively defined Gabbi requests.

class ThingApi(GabbiHypothesisTestCase):
    @given(text())
    def test_object_is_created(self, name):
        self.run_gabi({
            'tests': [{
                'name': 'create thing',
                'url': '/app/api/things/',
                'method': 'POST',
                'data': {'name': name}
            }]
        })