Testing
This skill provides comprehensive testing capabilities including test strategy, automation setup, Test-Driven Development (TDD), test writing best practices, coverage analysis, CI/CD integration, and web application testing with Playwright.
When to Use This Skill
- When setting up test infrastructure for a project
- When creating test strategies and test plans
- When writing unit, integration, or E2E tests
- When implementing TDD/test-first development
- When analyzing test coverage and quality
- When integrating tests into CI/CD pipelines
- When testing web applications with Playwright
- When debugging test failures or improving test reliability
- When writing test fixtures, mock data, or factory functions
- When mocking external dependencies (APIs, databases, file systems)
- When organizing test file structure and test suites
- When testing async code, Promises, or event-driven behavior
- When implementing snapshot tests for UI components
- When configuring test coverage thresholds
What This Skill Does
- Test Strategy: Designs comprehensive testing strategies (unit, integration, E2E)
- Test Automation: Sets up test frameworks and automation tools
- TDD Methodology: Implements Test-Driven Development workflows (Red-Green-Refactor)
- Test Writing: Writes focused, maintainable tests with proper patterns
- Coverage Analysis: Analyzes and improves test coverage
- CI/CD Integration: Integrates tests into continuous integration pipelines
- Web App Testing: Tests web applications using Playwright
- Test Quality: Improves test reliability and maintainability
Test Strategy
Test Pyramid
Recommended Distribution:
- Unit Tests: 70% - Fast, isolated, test individual functions
- Integration Tests: 20% - Test component interactions
- E2E Tests: 10% - Test complete user workflows
Test Types:
- Functional tests (happy path, edge cases, error handling)
- Non-functional tests (performance, security, accessibility)
- Regression tests (prevent breaking changes)
- Smoke tests (critical path verification)
Framework Selection
JavaScript/TypeScript:
- Jest, Vitest, Mocha for unit/integration
- Playwright, Cypress for E2E
- React Testing Library for component testing
Python:
- pytest for unit/integration
- Selenium, Playwright for E2E
- unittest for standard library testing
Java:
- JUnit for unit tests
- TestNG for integration
- Selenium for E2E
Go:
- Built-in testing package
- Testify for assertions
Rust:
- Built-in test framework
- Cargo test for running tests
Test-Driven Development (TDD)
TDD is a design technique, not just a testing technique. It produces better-designed, more maintainable code through small, disciplined steps.
Core Principle
Write tests before code. Always. TDD forces you to think about:
- What behavior do I need?
- How will I know it works?
- What's the simplest implementation?
The Three Laws (Never Violate)
- Write NO production code without a failing test first
- Write only enough test to demonstrate one failure
- Write only enough code to pass that test
Red-Green-Refactor Cycle
Phase 1: RED - Write Failing Test
- Write ONE test that defines desired behavior
- Run test - verify it FAILS
- Verify it fails for the RIGHT reason (not syntax error)
- DO NOT write implementation yet
Phase 2: GREEN - Minimal Implementation
- Write MINIMAL code to make test pass
- Resist urge to add extra features
- Run test - verify it PASSES
- If test still fails, fix implementation (not test)
Phase 3: REFACTOR - Clean Code
- Remove code duplication (DRY)
- Improve naming for clarity
- Extract complex logic into functions
- Run ALL tests - must stay green throughout
- Check test coverage on changed lines
After REFACTOR, start new RED phase for next behavior.
Test Writing Patterns
Arrange-Act-Assert (AAA)
Structure:
- Arrange: Set up test data and conditions
- Act: Execute the code being tested
- Assert: Verify the expected outcome
Example:
describe('UserService', () => {
it('should create user with valid data', async () => {
// Arrange
const userData = { email: 'test@example.com', name: 'Test User' };
// Act
const result = await userService.createUser(userData);
// Assert
expect(result).toHaveProperty('id');
expect(result.email).toBe(userData.email);
});
});
Given-When-Then (BDD Style)
Structure:
- Given: Initial context/preconditions
- When: Action/event that triggers behavior
- Then: Expected outcome
Test Organization
File Structure:
project/
├── src/
│ └── components/
│ └── User.jsx
├── tests/
│ ├── unit/
│ │ └── User.test.jsx
│ ├── integration/
│ │ └── UserAPI.test.js
│ └── e2e/
│ └── user-flow.spec.js
├── jest.config.js
└── playwright.config.js
Coverage Analysis
Coverage Goals
Recommended Thresholds:
- Lines: 80%+
- Functions: 80%+
- Branches: 80%+
- Statements: 80%+
Critical Paths:
- Always aim for 100% coverage on critical business logic
- Authentication and authorization
- Payment processing
- Data validation
Coverage Gaps
Common Gaps:
- Error handling paths
- Edge cases
- Boundary conditions
- Integration points
Improvement Strategies:
- Identify untested code paths
- Add tests for error scenarios
- Test edge cases and boundaries
- Increase integration test coverage
CI/CD Integration
Test Pipeline
Stages:
- Unit Tests: Fast feedback, run on every commit
- Integration Tests: Run on pull requests
- E2E Tests: Run before merging to main
- Performance Tests: Run on main branch
Quality Gates:
- All tests must pass
- Coverage must meet threshold
- No critical security issues
- Performance benchmarks met
Web Application Testing with Playwright
Helper Scripts
This skill includes Python helper scripts in scripts/:
with_server.py - Manages server lifecycle (supports multiple servers). Always run with --help first to see usage.
# Single server
python scripts/with_server.py --server "npm run dev" --port 5173 -- python your_automation.py
# Multiple servers (e.g., backend + frontend)
python scripts/with_server.py \
--server "cd backend && python server.py" --port 3000 \
--server "cd frontend && npm run dev" --port 5173 \
-- python your_automation.py
Decision Tree: Choosing Your Approach
User task → Is it static HTML?
├─ Yes → Read HTML file directly to identify selectors
│ ├─ Success → Write Playwright script using selectors
│ └─ Fails/Incomplete → Treat as dynamic (below)
│
└─ No (dynamic webapp) → Is the server already running?
├─ No → Run: python scripts/with_server.py --help
│ Then use the helper + write simplified Playwright script
│
└─ Yes → Reconnaissance-then-action:
1. Navigate and wait for networkidle
2. Take screenshot or inspect DOM
3. Identify selectors from rendered state
4. Execute actions with discovered selectors
Playwright Best Practices
- Use bundled scripts as black boxes - Use
--help to see usage, then invoke directly
- Use
sync_playwright() for synchronous scripts
- Always close the browser when done
- Use descriptive selectors:
text=, role=, CSS selectors, or IDs
- Add appropriate waits:
page.wait_for_selector() or page.wait_for_timeout()
- CRITICAL: Wait for
page.wait_for_load_state('networkidle') before inspection on dynamic apps
Example: Basic Playwright Script
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto('http://localhost:5173')
page.wait_for_load_state('networkidle') # CRITICAL: Wait for JS to execute
# ... your automation logic
browser.close()
Examples
See examples/ directory for:
element_discovery.py - Discovering buttons, links, and inputs on a page
static_html_automation.py - Using file:// URLs for local HTML
console_logging.py - Capturing console logs during automation
Reference Files
For detailed testing patterns and workflows, load reference files as needed:
references/framework_workflows.md - Framework-specific TDD workflows and examples for Python (pytest), JavaScript (Jest, Vitest), Java (JUnit), Go, Rust
references/test_patterns.md - Common test patterns, test organization, naming conventions, test doubles (mocks, stubs, spies), parametrization, and anti-patterns
references/webapp_testing.md - Web application testing patterns, Playwright best practices, and E2E testing strategies
references/TESTING_REPORT.template.md - Test quality report template with coverage metrics, audit findings, and recommendations
When working with specific frameworks or need detailed patterns, load the appropriate reference file.
Best Practices
Test Quality
- Isolation: Tests should be independent and runnable in any order
- Deterministic: Tests should produce consistent results
- Fast: Unit tests should run quickly (< 100ms each)
- Clear: Test names should describe what they test
- Maintainable: Tests should be easy to update when code changes
TDD Best Practices
- One Behavior Per Test: Each test verifies ONE behavior
- Descriptive Names: Test names describe the behavior being tested
- Independent Tests: Tests don't depend on each other
- Fast Tests: Mock external dependencies to keep tests fast
- Clear Assertions: Assertions clearly show what's being verified
Common Mistakes to Avoid
- ❌ Writing multiple tests at once (write one test at a time)
- ❌ Skipping refactor phase (always refactor after green)
- ❌ Implementation before test (delete code and start with test)
- ❌ Over-engineering in GREEN (simplest thing that passes)
- ❌ Writing test that passes immediately (must fail first)
Test Maintenance
- Review and update tests when requirements change
- Remove obsolete tests
- Refactor tests to reduce duplication
- Keep test data factories up to date
- Monitor test execution time
Integration with Other Skills
- debugging: Use when tests fail unexpectedly
- code-review: TDD produces code that's easier to review
- dead-code-removal: Tests help identify unused code
- performance: Use for performance testing strategies
Meta-Principle
TDD is a DESIGN technique, not a testing technique.
The cycle never changes: RED → GREEN → REFACTOR → Repeat
Writing tests first forces you to think about:
- What behavior do I need?
- How will I know it works?
- What's the simplest implementation?
This produces better-designed, more maintainable code.
1---2name: testing-23description: Comprehensive testing specialization covering test strategy, automation, TDD methodology, test writing, and web app testing. Use when setting up test infrastructure, writing tests, implementing TDD workflows, analyzing coverage, integrating tests into CI/CD, or testing web applications with Playwright. Framework-agnostic approach with framework-specific guidance via reference files.4---5
6# Testing
7
8This skill provides comprehensive testing capabilities including test strategy, automation setup, Test-Driven Development (TDD), test writing best practices, coverage analysis, CI/CD integration, and web application testing with Playwright.
9
10## When to Use This Skill
11
12- When setting up test infrastructure for a project
13- When creating test strategies and test plans
14- When writing unit, integration, or E2E tests
15- When implementing TDD/test-first development
16- When analyzing test coverage and quality
17- When integrating tests into CI/CD pipelines
18- When testing web applications with Playwright
19- When debugging test failures or improving test reliability
20- When writing test fixtures, mock data, or factory functions
21- When mocking external dependencies (APIs, databases, file systems)
22- When organizing test file structure and test suites
23- When testing async code, Promises, or event-driven behavior
24- When implementing snapshot tests for UI components
25- When configuring test coverage thresholds
26
27## What This Skill Does
28
291. **Test Strategy**: Designs comprehensive testing strategies (unit, integration, E2E)
302. **Test Automation**: Sets up test frameworks and automation tools
313. **TDD Methodology**: Implements Test-Driven Development workflows (Red-Green-Refactor)
324. **Test Writing**: Writes focused, maintainable tests with proper patterns
335. **Coverage Analysis**: Analyzes and improves test coverage
346. **CI/CD Integration**: Integrates tests into continuous integration pipelines
357. **Web App Testing**: Tests web applications using Playwright
368. **Test Quality**: Improves test reliability and maintainability
37
38## Test Strategy
39
40### Test Pyramid
41
42**Recommended Distribution:**
43
44- **Unit Tests**: 70% - Fast, isolated, test individual functions
45- **Integration Tests**: 20% - Test component interactions
46- **E2E Tests**: 10% - Test complete user workflows
47
48**Test Types:**
49
50- Functional tests (happy path, edge cases, error handling)
51- Non-functional tests (performance, security, accessibility)
52- Regression tests (prevent breaking changes)
53- Smoke tests (critical path verification)
54
55### Framework Selection
56
57**JavaScript/TypeScript:**
58
59- Jest, Vitest, Mocha for unit/integration
60- Playwright, Cypress for E2E
61- React Testing Library for component testing
62
63**Python:**
64
65- pytest for unit/integration
66- Selenium, Playwright for E2E
67- unittest for standard library testing
68
69**Java:**
70
71- JUnit for unit tests
72- TestNG for integration
73- Selenium for E2E
74
75**Go:**
76
77- Built-in testing package
78- Testify for assertions
79
80**Rust:**
81
82- Built-in test framework
83- Cargo test for running tests
84
85## Test-Driven Development (TDD)
86
87TDD is a **design technique**, not just a testing technique. It produces better-designed, more maintainable code through small, disciplined steps.
88
89### Core Principle
90
91**Write tests before code. Always.** TDD forces you to think about:
92
93- What behavior do I need?
94- How will I know it works?
95- What's the simplest implementation?
96
97### The Three Laws (Never Violate)
98
991. **Write NO production code** without a failing test first
1002. **Write only enough test** to demonstrate one failure
1013. **Write only enough code** to pass that test
102
103### Red-Green-Refactor Cycle
104
105**Phase 1: RED - Write Failing Test**
106
1071. Write ONE test that defines desired behavior
1082. Run test - verify it FAILS
1093. Verify it fails for the RIGHT reason (not syntax error)
1104. DO NOT write implementation yet
111
112**Phase 2: GREEN - Minimal Implementation**
113
1141. Write MINIMAL code to make test pass
1152. Resist urge to add extra features
1163. Run test - verify it PASSES
1174. If test still fails, fix implementation (not test)
118
119**Phase 3: REFACTOR - Clean Code**
120
1211. Remove code duplication (DRY)
1222. Improve naming for clarity
1233. Extract complex logic into functions
1244. Run ALL tests - must stay green throughout
1255. Check test coverage on changed lines
126
127After REFACTOR, start new RED phase for next behavior.
128
129## Test Writing Patterns
130
131### Arrange-Act-Assert (AAA)
132
133**Structure:**
134
1351. **Arrange**: Set up test data and conditions
1362. **Act**: Execute the code being tested
1373. **Assert**: Verify the expected outcome
138
139**Example:**
140
141```javascript
142describe('UserService', () => {
143 it('should create user with valid data', async () => {
144 // Arrange
145 const userData = { email: 'test@example.com', name: 'Test User' };
146
147 // Act
148 const result = await userService.createUser(userData);
149
150 // Assert
151 expect(result).toHaveProperty('id');
152 expect(result.email).toBe(userData.email);
153 });
154});
155```
156
157### Given-When-Then (BDD Style)
158
159**Structure:**
160
1611. **Given**: Initial context/preconditions
1622. **When**: Action/event that triggers behavior
1633. **Then**: Expected outcome
164
165### Test Organization
166
167**File Structure:**
168
169```
170project/
171├── src/
172│ └── components/
173│ └── User.jsx
174├── tests/
175│ ├── unit/
176│ │ └── User.test.jsx
177│ ├── integration/
178│ │ └── UserAPI.test.js
179│ └── e2e/
180│ └── user-flow.spec.js
181├── jest.config.js
182└── playwright.config.js
183```
184
185## Coverage Analysis
186
187### Coverage Goals
188
189**Recommended Thresholds:**
190
191- **Lines**: 80%+
192- **Functions**: 80%+
193- **Branches**: 80%+
194- **Statements**: 80%+
195
196**Critical Paths:**
197
198- Always aim for 100% coverage on critical business logic
199- Authentication and authorization
200- Payment processing
201- Data validation
202
203### Coverage Gaps
204
205**Common Gaps:**
206
207- Error handling paths
208- Edge cases
209- Boundary conditions
210- Integration points
211
212**Improvement Strategies:**
213
214- Identify untested code paths
215- Add tests for error scenarios
216- Test edge cases and boundaries
217- Increase integration test coverage
218
219## CI/CD Integration
220
221### Test Pipeline
222
223**Stages:**
224
2251. **Unit Tests**: Fast feedback, run on every commit
2262. **Integration Tests**: Run on pull requests
2273. **E2E Tests**: Run before merging to main
2284. **Performance Tests**: Run on main branch
229
230**Quality Gates:**
231
232- All tests must pass
233- Coverage must meet threshold
234- No critical security issues
235- Performance benchmarks met
236
237## Web Application Testing with Playwright
238
239### Helper Scripts
240
241This skill includes Python helper scripts in `scripts/`:
242
243- **`with_server.py`** - Manages server lifecycle (supports multiple servers). Always run with `--help` first to see usage.
244
245 ```bash
246 # Single server
247 python scripts/with_server.py --server "npm run dev" --port 5173 -- python your_automation.py
248
249 # Multiple servers (e.g., backend + frontend)
250 python scripts/with_server.py \
251 --server "cd backend && python server.py" --port 3000 \
252 --server "cd frontend && npm run dev" --port 5173 \
253 -- python your_automation.py
254 ```
255
256### Decision Tree: Choosing Your Approach
257
258```
259User task → Is it static HTML?
260 ├─ Yes → Read HTML file directly to identify selectors
261 │ ├─ Success → Write Playwright script using selectors
262 │ └─ Fails/Incomplete → Treat as dynamic (below)
263 │
264 └─ No (dynamic webapp) → Is the server already running?
265 ├─ No → Run: python scripts/with_server.py --help
266 │ Then use the helper + write simplified Playwright script
267 │
268 └─ Yes → Reconnaissance-then-action:
269 1. Navigate and wait for networkidle
270 2. Take screenshot or inspect DOM
271 3. Identify selectors from rendered state
272 4. Execute actions with discovered selectors
273```
274
275### Playwright Best Practices
276
277- **Use bundled scripts as black boxes** - Use `--help` to see usage, then invoke directly
278- Use `sync_playwright()` for synchronous scripts
279- Always close the browser when done
280- Use descriptive selectors: `text=`, `role=`, CSS selectors, or IDs
281- Add appropriate waits: `page.wait_for_selector()` or `page.wait_for_timeout()`
282- **CRITICAL**: Wait for `page.wait_for_load_state('networkidle')` before inspection on dynamic apps
283
284### Example: Basic Playwright Script
285
286```python
287from playwright.sync_api import sync_playwright
288
289with sync_playwright() as p:
290 browser = p.chromium.launch(headless=True)
291 page = browser.new_page()
292 page.goto('http://localhost:5173')
293 page.wait_for_load_state('networkidle') # CRITICAL: Wait for JS to execute
294 # ... your automation logic
295 browser.close()
296```
297
298### Examples
299
300See `examples/` directory for:
301
302- `element_discovery.py` - Discovering buttons, links, and inputs on a page
303- `static_html_automation.py` - Using file:// URLs for local HTML
304- `console_logging.py` - Capturing console logs during automation
305
306## Reference Files
307
308For detailed testing patterns and workflows, load reference files as needed:
309
310- **`references/framework_workflows.md`** - Framework-specific TDD workflows and examples for Python (pytest), JavaScript (Jest, Vitest), Java (JUnit), Go, Rust
311- **`references/test_patterns.md`** - Common test patterns, test organization, naming conventions, test doubles (mocks, stubs, spies), parametrization, and anti-patterns
312- **`references/webapp_testing.md`** - Web application testing patterns, Playwright best practices, and E2E testing strategies
313- **`references/TESTING_REPORT.template.md`** - Test quality report template with coverage metrics, audit findings, and recommendations
314
315When working with specific frameworks or need detailed patterns, load the appropriate reference file.
316
317## Best Practices
318
319### Test Quality
320
3211. **Isolation**: Tests should be independent and runnable in any order
3222. **Deterministic**: Tests should produce consistent results
3233. **Fast**: Unit tests should run quickly (< 100ms each)
3244. **Clear**: Test names should describe what they test
3255. **Maintainable**: Tests should be easy to update when code changes
326
327### TDD Best Practices
328
3291. **One Behavior Per Test**: Each test verifies ONE behavior
3302. **Descriptive Names**: Test names describe the behavior being tested
3313. **Independent Tests**: Tests don't depend on each other
3324. **Fast Tests**: Mock external dependencies to keep tests fast
3335. **Clear Assertions**: Assertions clearly show what's being verified
334
335### Common Mistakes to Avoid
336
337- ❌ Writing multiple tests at once (write one test at a time)
338- ❌ Skipping refactor phase (always refactor after green)
339- ❌ Implementation before test (delete code and start with test)
340- ❌ Over-engineering in GREEN (simplest thing that passes)
341- ❌ Writing test that passes immediately (must fail first)
342
343### Test Maintenance
344
345- Review and update tests when requirements change
346- Remove obsolete tests
347- Refactor tests to reduce duplication
348- Keep test data factories up to date
349- Monitor test execution time
350
351## Integration with Other Skills
352
353- **debugging**: Use when tests fail unexpectedly
354- **code-review**: TDD produces code that's easier to review
355- **dead-code-removal**: Tests help identify unused code
356- **performance**: Use for performance testing strategies
357
358## Meta-Principle
359
360```
361TDD is a DESIGN technique, not a testing technique.
362
363The cycle never changes: RED → GREEN → REFACTOR → Repeat
364
365Writing tests first forces you to think about:
366- What behavior do I need?
367- How will I know it works?
368- What's the simplest implementation?
369
370This produces better-designed, more maintainable code.
371```