Skills · Coding

Python Testing Patterns

Unverified29/40

Implement comprehensive testing strategies with pytest, fixtures, mocking, and test-driven development. Use when writing Python tests, setting up test suites, or implementing testing best practices.

Originally by wshobson · MIT

Claude CodePartialHas SKILL.md but declares no allowed-tools — Claude Code will ask for permission each time
Cursor·UnknownWe have not crawled the repo tree, so we will not guess
Codex·UnknownWe have not crawled the repo tree, so we will not guess
Gemini CLI·UnknownThe spec defines no detection rule for Gemini
Copilot·UnknownWe have not crawled the repo tree, so we will not guess
npx agentalley add python-testing-patterns

This command does not work yet — the CLI is still being built. Until then, use Raw in the reader below to take the file.

Who is stuck, and on what

Implement comprehensive testing strategies with pytest, fixtures, mocking, and test-driven development. Use when writing Python tests, setting up test suites, or implementing testing best practices.

The whole source

No sign-in, no blur, nothing truncated
python-testing-patterns/SKILL.md279 lines7.1 KBRawView on GitHub
Frontmatter — 2 properties
namepython-testing-patterns
descriptionImplement comprehensive testing strategies with pytest, fixtures, mocking, and test-driven development. Use when writing Python tests, setting up test suites, or implementing testing best practices.
1---
2name: python-testing-patterns
3description: Implement comprehensive testing strategies with pytest, fixtures, mocking, and test-driven development. Use when writing Python tests, setting up test suites, or implementing testing best practices.
4---A5No allowed-tools declared — no way to tell what this skill may touch
5 
6# Python Testing Patterns
7 
8Comprehensive guide to implementing robust testing strategies in Python using pytest, fixtures, mocking, parameterization, and test-driven development practices.
9 
10## When to Use This Skill
11 
12- Writing unit tests for Python code
13- Setting up test suites and test infrastructure
14- Implementing test-driven development (TDD)
15- Creating integration tests for APIs and services
16- Mocking external dependencies and services
17- Testing async code and concurrent operations
18- Setting up continuous testing in CI/CD
19- Implementing property-based testing
20- Testing database operations
21- Debugging failing tests
22 
23## Core Concepts
24 
25### 1. Test Types
26 
27- **Unit Tests**: Test individual functions/classes in isolation
28- **Integration Tests**: Test interaction between components
29- **Functional Tests**: Test complete features end-to-end
30- **Performance Tests**: Measure speed and resource usage
31 
32### 2. Test Structure (AAA Pattern)
33 
34- **Arrange**: Set up test data and preconditions
35- **Act**: Execute the code under test
36- **Assert**: Verify the results
37 
38### 3. Test Coverage
39 
40- Measure what code is exercised by tests
41- Identify untested code paths
42- Aim for meaningful coverage, not just high percentages
43 
44### 4. Test Isolation
45 
46- Tests should be independent
47- No shared state between tests
48- Each test should clean up after itself
49 
50## Quick Start
51 
52```python
53# test_example.py
54def add(a, b):
55 return a + b
56 
57def test_add():
58 """Basic test example."""
59 result = add(2, 3)
60 assert result == 5
61 
62def test_add_negative():
63 """Test with negative numbers."""
64 assert add(-1, 1) == 0
65 
66# Run with: pytest test_example.py
67```
68 
69## Detailed patterns and worked examples
70 
71Detailed pattern documentation lives in `references/details.md`. Read that file when the navigation tier above is insufficient.
72 
73## Testing Best Practices
74 
75### Test Organization
76 
77```python
78# tests/
79# __init__.py
80# conftest.py # Shared fixtures
81# test_unit/ # Unit tests
82# test_models.py
83# test_utils.py
84# test_integration/ # Integration tests
85# test_api.py
86# test_database.py
87# test_e2e/ # End-to-end tests
88# test_workflows.py
89```
90 
91### Test Naming Convention
92 
93A common pattern: `test_<unit>_<scenario>_<expected_outcome>`. Adapt to your team's preferences.
94 
95```python
96# Pattern: test_<unit>_<scenario>_<expected>
97def test_create_user_with_valid_data_returns_user():
98 ...
99 
100def test_create_user_with_duplicate_email_raises_conflict():
101 ...
102 
103def test_get_user_with_unknown_id_returns_none():
104 ...
105 
106# Good test names - clear and descriptive
107def test_user_creation_with_valid_data():
108 """Clear name describes what is being tested."""
109 pass
110 
111def test_login_fails_with_invalid_password():
112 """Name describes expected behavior."""
113 pass
114 
115def test_api_returns_404_for_missing_resource():
116 """Specific about inputs and expected outcomes."""
117 pass
118 
119# Bad test names - avoid these
120def test_1(): # Not descriptive
121 pass
122 
123def test_user(): # Too vague
124 pass
125 
126def test_function(): # Doesn't explain what's tested
127 pass
128```
129 
130### Testing Retry Behavior
131 
132Verify that retry logic works correctly using mock side effects.
133 
134```python
135from unittest.mock import Mock
136 
137def test_retries_on_transient_error():
138 """Test that service retries on transient failures."""
139 client = Mock()
140 # Fail twice, then succeed
141 client.request.side_effect = [
142 ConnectionError("Failed"),
143 ConnectionError("Failed"),
144 {"status": "ok"},
145 ]
146 
147 service = ServiceWithRetry(client, max_retries=3)
148 result = service.fetch()A4This skill pulls in web or user content but never says to treat that content as data. A signal, not proof.
149 
150 assert result == {"status": "ok"}
151 assert client.request.call_count == 3
152 
153def test_gives_up_after_max_retries():
154 """Test that service stops retrying after max attempts."""
155 client = Mock()
156 client.request.side_effect = ConnectionError("Failed")
157 
158 service = ServiceWithRetry(client, max_retries=3)
159 
160 with pytest.raises(ConnectionError):
161 service.fetch()
162 
163 assert client.request.call_count == 3
164 
165def test_does_not_retry_on_permanent_error():
166 """Test that permanent errors are not retried."""
167 client = Mock()
168 client.request.side_effect = ValueError("Invalid input")
169 
170 service = ServiceWithRetry(client, max_retries=3)
171 
172 with pytest.raises(ValueError):
173 service.fetch()
174 
175 # Only called once - no retry for ValueError
176 assert client.request.call_count == 1
177```
178 
179### Mocking Time with Freezegun
180 
181Use freezegun to control time in tests for predictable time-dependent behavior.
182 
183```python
184from freezegun import freeze_time
185from datetime import datetime, timedelta
186 
187@freeze_time("2026-01-15 10:00:00")
188def test_token_expiry():
189 """Test token expires at correct time."""
190 token = create_token(expires_in_seconds=3600)
191 assert token.expires_at == datetime(2026, 1, 15, 11, 0, 0)
192 
193@freeze_time("2026-01-15 10:00:00")
194def test_is_expired_returns_false_before_expiry():
195 """Test token is not expired when within validity period."""
196 token = create_token(expires_in_seconds=3600)
197 assert not token.is_expired()
198 
199@freeze_time("2026-01-15 12:00:00")
200def test_is_expired_returns_true_after_expiry():
201 """Test token is expired after validity period."""
202 token = Token(expires_at=datetime(2026, 1, 15, 11, 30, 0))
203 assert token.is_expired()
204 
205def test_with_time_travel():
206 """Test behavior across time using freeze_time context."""
207 with freeze_time("2026-01-01") as frozen_time:
208 item = create_item()
209 assert item.created_at == datetime(2026, 1, 1)
210 
211 # Move forward in time
212 frozen_time.move_to("2026-01-15")
213 assert item.age_days == 14
214```
215 
216### Test Markers
217 
218```python
219# test_markers.py
220import pytest
221 
222@pytest.mark.slow
223def test_slow_operation():
224 """Mark slow tests."""
225 import time
226 time.sleep(2)
227 
228 
229@pytest.mark.integration
230def test_database_integration():
231 """Mark integration tests."""
232 pass
233 
234 
235@pytest.mark.skip(reason="Feature not implemented yet")
236def test_future_feature():
237 """Skip tests temporarily."""
238 pass
239 
240 
241@pytest.mark.skipif(os.name == "nt", reason="Unix only test")
242def test_unix_specific():
243 """Conditional skip."""
244 pass
245 
246 
247@pytest.mark.xfail(reason="Known bug #123")
248def test_known_bug():
249 """Mark expected failures."""
250 assert False
251 
252 
253# Run with:
254# pytest -m slow # Run only slow tests
255# pytest -m "not slow" # Skip slow tests
256# pytest -m integration # Run integration tests
257```
258 
259### Coverage Reporting
260 
261```bash
262# Install coverage
263pip install pytest-cov
264 
265# Run tests with coverage
266pytest --cov=myapp tests/
267 
268# Generate HTML report
269pytest --cov=myapp --cov-report=html tests/
270 
271# Fail if coverage below threshold
272pytest --cov=myapp --cov-fail-under=80 tests/
273 
274# Show missing lines
275pytest --cov=myapp --cov-report=term-missing tests/
276```
277 
278For advanced patterns (async testing, monkeypatching, property-based testing, database testing, CI/CD integration, and configuration), see [references/advanced-patterns.md](references/advanced-patterns.md)
279 

Reviews

Installed this one?Write the first review and take the Trailblazer badge.

Reviews only open after a real install, so this is empty — and we leave it empty rather than invent one.

Alternatives

Also in Coding