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