From python-testing
Pytest-specific conventions: function-style tests, fixtures, parametrize, and exception testing
How this skill is triggered — by the user, by Claude, or both
Slash command
/python-testing:pytest-conventionsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
```python
# Good
def test_create_order(fake_repo: OrderRepository, customer_factory):
customer = customer_factory()
order = create_order(customer.id, "p1", fake_repo)
assert order.customer_id == customer.id
# Bad
class TestOrderCreation:
def setUp(self):
self.repo = InMemoryOrderRepository()
def test_create_order(self):
order = create_order("c1", "p1", self.repo)
assert order is not None
pytest.fixture for shared setup logic instead of class inheritance# Good
@pytest.fixture
def fake_repo() -> OrderRepository:
return InMemoryOrderRepository()
@pytest.fixture
def customer_factory():
def _factory(name: str = "John", email: str = "[email protected]") -> Customer:
return Customer(uuid4(), name, email)
return _factory
def test_order_creation(fake_repo: OrderRepository, customer_factory):
customer = customer_factory(name="Jane")
order = create_order(customer.id, "p1", fake_repo)
assert fake_repo.get(order.id) is not None
# Bad
class BaseTestCase:
def setUp(self):
self.repo = InMemoryOrderRepository()
self.customer = Customer(uuid4(), "John", "[email protected]")
class TestOrder(BaseTestCase):
def test_order(self):
order = create_order(self.customer.id, "p1", self.repo)
function (default), module, or session@pytest.mark.parametrize to test multiple scenarios with the same logic# Good
@pytest.mark.parametrize("age,is_valid", [
(17, False),
(18, True),
(25, True),
(150, False),
])
def test_customer_age_validation(age: int, is_valid: bool):
if is_valid:
customer = Customer(uuid4(), "Test", "[email protected]", age)
assert customer.age == age
else:
with pytest.raises(ValueError):
Customer(uuid4(), "Test", "[email protected]", age)
# Bad
def test_age_17_invalid():
with pytest.raises(ValueError):
Customer(uuid4(), "Test", "[email protected]", 17)
def test_age_18_valid():
customer = Customer(uuid4(), "Test", "[email protected]", 18)
assert customer.age == 18
pytest.raises(ExceptionType) context manager to verify exceptions# Good
def test_cannot_place_already_placed_order():
order = Order(uuid4(), uuid4(), Money(100, "USD"), status="placed")
with pytest.raises(ValueError, match="already placed"):
order.place()
# Bad
def test_cannot_place_already_placed_order():
order = Order(uuid4(), uuid4(), Money(100, "USD"), status="placed")
try:
order.place()
assert False
except:
pass
match parameter to validate exception messages when relevantnpx claudepluginhub remihuguet/rems-buddy --plugin python-testingpytest testing framework conventions and practices. Invoke whenever task involves any interaction with pytest — writing tests, configuring pytest, fixtures, parametrize, mocking, debugging test failures, or coverage.
Writes pytest tests using fixtures, parametrization, mocking, async patterns, and AAA structure. Use for creating or updating Python test files, not unittest.
Provides pytest patterns for Python testing: fixtures, parametrization, mocking, markers, and exception testing. Useful when writing or reviewing unit/integration tests.