Use when writing or reviewing tests, designing test strategies, debugging flaky tests, or assessing test coverage and quality. Covers unit, integration, e2e, and agent/LLM evaluations.
Tests exist to give you the courage to change code. If they don't, they're wrong.
/\ e2e (few, slow, high value)
/ \
/----\ integration (some)
/ \
/--------\ unit (many, fast)
Invert this and your suite becomes slow, flaky, and feared.
(FIRST: Fast, Isolated, Repeatable, Self-validating, Timely)
def test_<subject>_<scenario>_<expected_result>():
...
def test_parse_date_invalid_format_raises_valueerror():
...
A failing test name should explain the bug.
def test_transfer_moves_funds():
# Arrange
sender = Account(balance=100)
receiver = Account(balance=0)
# Act
transfer(sender, receiver, amount=30)
# Assert
assert sender.balance == 70
assert receiver.balance == 30
One "act" per test. Multiple asserts are fine if they verify the same action.
pytest fixtures.make_user()) or libraries like factory-boy, Faker.respx/responses, not by patching requests internals.For pure functions and parsers, add hypothesis:
from hypothesis import given, strategies as st
@given(st.text())
def test_roundtrip(s):
assert decode(encode(s)) == s
Finds edge cases humans miss: empty strings, unicode, large inputs.
docker-compose used for dev).testcontainers for ephemeral DB/queue/cache per test session.data-testid attributes.assert result is not None.time.sleep, now()), order dependency, shared state, network, random seeds.freezegun). Fix seeds. Isolate state. Remove network from unit tests.assert True placeholders committed.conftest.py no one understands.sleep(5) waiting for an async operation.