Contract Testing in Python
Python clean code tip:
Use contract testing when you want to verify the same behavior for different implementations.
Example:
import json import pathlib from dataclasses import dataclass import pytest @dataclass class User: username: str class InMemoryUserRepository: def __init__(self): self._users = [] def add(self, user): self._users.append(user) def get_by_username(self, username): return next(user for user in self._users if user.username == username) class JSONUserRepository: def __init__(self, file_path): self._users = json.load(pathlib.Path(file_path).open()) def add(self, user): self._users.append(user) def get_by_username(self, username): return next(user for user in self._users if user.username == username) class UserRepositoryContract: @pytest.fixture def repository(self): raise NotImplementedError('Not Implemented Yet') @pytest.fixture def username(self): return 'johndoe' @pytest.fixture def user(self, username): return User(username=username) def test_added_user_is_retrieved_by_username(self, username, user, repository): repository.add(user) assert repository.get_by_username(user.username).username == username class TestInMemoryUserRepository(UserRepositoryContract): @pytest.fixture def repository(self): return InMemoryUserRepository() class TestInJSONUserRepository(UserRepositoryContract): @pytest.fixture def repository(self, tmp_path): users_file = tmp_path/"user.json" users_file.write_text(json.dumps([])) return JSONUserRepository(users_file)