💻 Coding
pytest Fixture Design from a Test Plan
Design pytest fixtures, factories, and parametrize tables from a test plan, with scope notes and no hidden network I/O.
0Reviews
Prompt
Act as a Python test architect. Design pytest fixtures from a test plan. Prefer factories over one giant conftest. Do not hide network or clock I/O inside autouse fixtures unless Inputs demand it. Inputs: - Package / app under test: [App] - Python and pytest versions I actually run: [Versions] - Test plan or failing tests: [Plan] - I/O involved: [DB, HTTP, files, time] - What already exists: [conftest, factories] - Style: [pytest-style, assert vs pytest.raises] - Constraints: [no network in unit tests, tmp_path only, etc.] Generate: 1. Fixture graph: name, scope (function/session), what it yields, what it depends on. 2. conftest.py split: which fixtures go root vs tests/unit vs tests/integration. 3. Code: factories and fixtures. Real pytest. 4. Parametrize table for the riskiest behavior. Include one row that should fail if the bug is present. 5. Anti-patterns I removed: autouse that patches time globally, session-scoped mutable lists, real HTTP. 6. How to run: exact commands from Inputs. If none, say NEED COMMAND. Constraints: - Do not invent a pytest plugin version. - Unit fixtures must not call the network. Mark integration explicitly. - No terraform, Next.js, traceback, regex, git, or README clones.
Instructions
Replace every [bracket] with your details before running. Works on ChatGPT, Claude, and Gemini.
Examples
Example Input
App: tidefold.noaa client, function fetch_station(station_id, session) Versions: Python 3.12, pytest 8.3 Plan: unit tests for URL build and 404; do not hit CO-OPS; 404 raises StationNotFound; empty body raises ParseError I/O: HTTP via a Session-like object we pass in Exists: nothing Style: pytest.raises Constraints: no network in unit tests, fake session
Example Output
1. Fixture graph
- fake_session (function): queue of (status, text). No net.
- client (function): NOAAClient(session=fake_session).
No autouse. No session-scoped mutables.
2. Split
tests/unit/conftest.py holds FakeSession, fake_session, client. tests/integration/ empty.
3. Code
class FakeSession:
def __init__(self):
self.calls, self.queue = [], []
def queue_response(self, status, text):
self.queue.append((status, text))
def get(self, url, **kwargs):
self.calls.append((url, kwargs))
status, text = self.queue.pop(0)
class R:
def __init__(self, status, text):
self.status_code, self.text = status, text
def json(self):
import json
return json.loads(self.text)
return R(status, text)
@pytest.fixture
def fake_session():
return FakeSession()
@pytest.fixture
def client(fake_session):
return NOAAClient(session=fake_session)
@pytest.mark.parametrize("status,body,exc", [
(404, "{}", StationNotFound),
(200, "", ParseError),
])
def test_errors(client, fake_session, status, body, exc):
fake_session.queue_response(status, body)
with pytest.raises(exc):
client.fetch_station("9435380")
def test_url_includes_station(client, fake_session):
fake_session.queue_response(200, '{"id": "9435380"}')
client.fetch_station("9435380")
url, _ = fake_session.calls[0]
assert "9435380" in url
4. Fail row
If 404 does not raise StationNotFound, row 1 fails. That is the point.
5. Removed
No autouse clock. No live NOAA. No session-scoped queue that leaks.
6. Run
pytest tests/unit -q
NEED COMMAND if the package is not on PYTHONPATH.