Pytest is a powerful testing framework that emphasizes modularity via fixtures and scalability via parametrization. It simplifies setup/teardown logic and enables complex test matrices with minimal code.
When to Use
Resource Intensive Tests: Using scoped fixtures for database or API connections to avoid redundant setup.
Input Combinations: Using parametrization to test a single function against dozens of inputs.
Async Codebases: Testing coroutines directly without manual event loop management.
Decision Tree
Is the setup expensive (e.g., creating a DB)?
YES: Use a fixture with scope='session' or scope='module'.
Do you need to cleanup after a test?
YES: Use a yield fixture.
Do you have 3+ similar test cases for one function?
YES: Use @pytest.mark.parametrize.
Workflows
1. Defining a Scoped Setup/Teardown
Create a fixture using the @pytest.fixture(scope="module") decorator for expensive resources like database connections.
Use yield to provide the resource to tests.
Add cleanup code (e.g., closing the connection) after the yield statement.
Request the fixture by name in any test function within the module.
2. Matrix Testing with Stacked Parametrize
Apply @pytest.mark.parametrize("user", ["admin", "guest"]) to a test.
Apply a second @pytest.mark.parametrize("action", ["read", "write"]) to the same test.
Pytest will run the test 4 times, once for each combination (admin-read, admin-write, etc.).
3. Testing Async Code
Install pytest-asyncio.
Mark the test function with @pytest.mark.asyncio.
Define the test as an async def.
Use await for the code under test and assertions.
Non-Obvious Insights
Fixture Caching: Fixtures are executed once per requested scope and the return value is cached for all tests in that scope.
Reverse Teardown: Teardown logic in yield fixtures is executed in the exact reverse order of the setup sequence.
Auto-Async Marking: Modern pytest-asyncio can be configured to treat all async def tests as async without needing the explicit decorator on every function.
Evidence
"pytest won’t execute them again for that test... return values are cached." - Pytest Docs
"Yield fixtures yield instead of return... Any teardown code for that fixture is placed after the yield." - Pytest Docs
"provides support for coroutines as test functions. This allows users to await code inside their tests." - pytest-asyncio
Scripts
scripts/pytest-patterns_tool.py: Examples of fixtures, parametrization, and async tests.
scripts/pytest-patterns_tool.js: (Comparison) Equivalent logic in Vitest/Jest.
1---2name: forceinjection-domain-driven-design-skills-pytest-patterns3description: Pytest Advanced Patterns4---56# Pytest Advanced Patterns78## Overview9Pytest is a powerful testing framework that emphasizes modularity via fixtures and scalability via parametrization. It simplifies setup/teardown logic and enables complex test matrices with minimal code.1011## When to Use12- **Resource Intensive Tests**: Using scoped fixtures for database or API connections to avoid redundant setup.13- **Input Combinations**: Using parametrization to test a single function against dozens of inputs.14- **Async Codebases**: Testing coroutines directly without manual event loop management.1516## Decision Tree171. Is the setup expensive (e.g., creating a DB)? 18 - YES: Use a fixture with `scope='session'` or `scope='module'`.192. Do you need to cleanup after a test? 20 - YES: Use a `yield` fixture.213. Do you have 3+ similar test cases for one function? 22 - YES: Use `@pytest.mark.parametrize`.2324## Workflows2526### 1. Defining a Scoped Setup/Teardown271. Create a fixture using the `@pytest.fixture(scope="module")` decorator for expensive resources like database connections.282. Use `yield` to provide the resource to tests.293. Add cleanup code (e.g., closing the connection) after the `yield` statement.304. Request the fixture by name in any test function within the module.3132### 2. Matrix Testing with Stacked Parametrize331. Apply `@pytest.mark.parametrize("user", ["admin", "guest"])` to a test.342. Apply a second `@pytest.mark.parametrize("action", ["read", "write"])` to the same test.353. Pytest will run the test 4 times, once for each combination (admin-read, admin-write, etc.).3637### 3. Testing Async Code381. Install `pytest-asyncio`.392. Mark the test function with `@pytest.mark.asyncio`.403. Define the test as an `async def`.414. Use `await` for the code under test and assertions.4243## Non-Obvious Insights44- **Fixture Caching**: Fixtures are executed once per requested scope and the return value is cached for all tests in that scope.45- **Reverse Teardown**: Teardown logic in `yield` fixtures is executed in the exact reverse order of the setup sequence.46- **Auto-Async Marking**: Modern `pytest-asyncio` can be configured to treat all `async def` tests as async without needing the explicit decorator on every function.4748## Evidence49- "pytest won’t execute them again for that test... return values are cached." - [Pytest Docs](https://docs.pytest.org/en/stable/how-to/fixtures.html)50- "Yield fixtures yield instead of return... Any teardown code for that fixture is placed after the yield." - [Pytest Docs](https://docs.pytest.org/en/stable/how-to/fixtures.html)51- "provides support for coroutines as test functions. This allows users to await code inside their tests." - [pytest-asyncio](https://pytest-asyncio.readthedocs.io/en/latest/)5253## Scripts54- `scripts/pytest-patterns_tool.py`: Examples of fixtures, parametrization, and async tests.55- `scripts/pytest-patterns_tool.js`: (Comparison) Equivalent logic in Vitest/Jest.5657## Dependencies58- `pytest`59- `pytest-asyncio`6061## References62- [references/README.md](references/README.md)6364---65> Source: [ForceInjection/domain-driven-design-skills](https://github.com/ForceInjection/domain-driven-design-skills) — distributed by [TomeVault](https://tomevault.io).66<!-- tomevault:4.0:skill_md:2026-05-22 -->
Run npx skillmds@latest add tomevault-io/forceinjection-domain-driven-design-skills-pytest-patterns in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Pytest Advanced Patterns It is listed under Coding & Dev Tools on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Independent scanners report: SkillSpector: PASS, Skill Scanner: PASS. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
tomevault-io (@tomevault-io) published this skill. Their other Agent Skills are listed on their SkillMD profile.