Advices from Haki Benita

A class based approach to writing tests in Python

Tests can be a bummer to write but even a bigger nightmare to maintain .

When we noticed we are putting off simple tasks just because we were afraid to update some monster test case, we started looking for more creative ways to simplify the process of writing and maintaining tests.

In this article I will describe a class based approach to writing tests.

Before we start writing code let’s set some goals:

  • Extensive We want our tests to cover as many scenarios as possible.

    We hope a solid platform for writing tests will make it easier for us to adapt to changes and cover more grounds.

  • Expressive Good tests tell a story.

    Issues become irrelevant and documents get lost but tests must always pass this is why we treat our tests as specs. Writing good tests can help newcomers (and future self) to understand all the edge cases and micro-decisions made during development.

  • Maintainable As requirements and implementations change we want to adapt quickly with as little effort as possible. (factory as a service)

One of the most challenging aspects of writing good tests is maintaining test fixtures.

Good test fixtures motivate developers to write better tests, and bad fixtures can cripple a system to a point where developers fear and avoid them all together.

The key to maintaining good fixtures is to find a good balance between flexibility and usability.

Good fixtures are ones that are easy to use and easy to modify.

In my latest article for RealPython I share some insights on how to maintain good test fixtures for Django models using Pytest.

The article covers everything from setting up Pytest for a Django project, creating test fixtures and how to create dependency between fixtures.

The article focuses on a pattern called “factory as a service”. Using this pattern, you can create fixture for Django models that depend on other fixtures.

This makes it easier to set up data for tests and focus on the the scenario at hand rather than setting up the data.