Testing
See Verify for more information on the testing phase of the SDLC.
Test Strategy
Before writing any tests, define a strategy so you invest your testing effort where it matters most.
The
Structure your test suite following the test pyramid:
| Layer | Proportion | Speed | What it catches |
|---|---|---|---|
| Unit Tests | ~70% | Fast (ms) | Logic errors in individual functions and components |
| Integration Tests | ~20% | Medium (seconds) | Contract and communication issues between modules |
| E2E Tests | ~10% | Slow (seconds-minutes) | Broken user journeys through the real UI |
If your E2E suite takes hours to run and breaks constantly, you probably have an inverted pyramid. Push more testing down to the unit and integration layers where tests are faster and more reliable.
Not all code is equally risky. Focus testing effort on:
- Authentication and authorisation - security-critical
- Payment and financial logic - money is always high-risk
- Core business workflows - the features your users depend on daily
- Data mutations - creating, updating, and deleting data
Low-risk areas (static pages, minor UI tweaks) need less coverage.
Code Coverage
is a useful signal, not a goal. Do not chase 100% coverage - that wastes time testing trivial code. A pragmatic target is 70-80% meaningful coverage of business logic.
- Use factories, fixtures, or builders to create test data
- Never couple tests to production data or shared mutable state
- Each test should set up and tear down its own data
As a solo developer, focus testing effort on the critical user paths first: sign-up, payment, core workflow. Manual QA is acceptable for edge cases and low-risk features at the early stages. Automated tests for critical paths are non-negotiable.
Shift-Left Testing
means moving testing activities earlier in the lifecycle, where bugs are cheapest to fix.
(Test-Driven Development)
Consider using TDD for complex business logic:
- Red - Write a failing test that defines the expected behaviour
- Green - Write the minimum code to make the test pass
- Refactor - Clean up the code while keeping the test green
TDD is not required for every piece of code, but it is particularly valuable for utility functions, data transformations, and business rules.
Static analysis is the cheapest form of testing - it catches bugs before your code even runs:
- TypeScript - catches type errors at compile time
- ESLint - catches anti-patterns and potential bugs
- SonarQube - deeper analysis for code smells and complexity
See Verify - Shift-Left Testing for more detail on TDD, BDD, and static analysis practices.
Testing Links
- Testing in Next.js and React
- Cypress React Tutorial
- Review the testing resources saved in Todoist
- Set up testing throughout the application based on its requirements
-
Testing Trophy and Testing Classifications
- (ESLint, TypeScript) - Done automatically in VS Code e.g. typos and type errors
- Unit tests (Jest / Vitest / React Testing Library)
- Integration tests (React Testing Library / Cypress)
- (Playwright / Cypress)
- Use AI to write some simple tests
Static Tests
- Static tests are done automatically in VS Code e.g. typos and type errors
- Ensure static testing libraries are set up such as ESLint or TypeScript
Unit Tests
- To create unit tests, use AI to write the tests - see the "Testing Prompts" section of the Obsidian note on AI Prompts - and then review the tests and make improvements
- Use a testing library such as Jest or React Testing Library
- If using Vite, use Vitest for unit tests
Integration Tests
- To create integration tests, use AI to write the tests - see the "Testing Prompts" section of the Obsidian note on AI Prompts - and then review the tests and make improvements
- Use a testing library such as React Testing Library or Cypress
E2E Tests
- For E2E tests, use a testing library such as Playwright or Cypress
Non-Functional Testing
Functional correctness is necessary but not sufficient. Non-functional quality attributes must be tested explicitly before release.
Performance Testing
- Before releasing the project, test the performance of the project using these tools:
- Lighthouse - Chrome DevTools extension
- WebPageTest - Lets you test the performance of your site across multiple locations and devices
- PageSpeed Insights - Chrome DevTools extension
- For API or backend , use k6 to run simple load tests
(WCAG)
Ensure your product is usable by everyone. Target WCAG 2.1 AA as a minimum:
- Automated tools (catch ~30% of issues):
- axe DevTools - browser extension for accessibility auditing
- Lighthouse accessibility audit (built into Chrome DevTools)
- Manual testing (catches the rest):
- Navigate your app using only the keyboard
- Test with a screen reader (NVDA on Windows, VoiceOver on Mac)
- Check colour contrast ratios
- Run automated scans with Snyk and Trivy (as set up in Development - Security)
- For web applications, consider OWASP ZAP for automated penetration testing
- Review against the OWASP Top 10 checklist
Common Testing Pitfalls
- Testing only the happy path: Most bugs live in edge cases - empty inputs, network failures, boundary values, concurrent access. Explicitly test error scenarios.
- Flaky tests: Tests that pass sometimes and fail sometimes destroy trust in the test suite. Teams start ignoring failures, and real bugs slip through. Fix or delete flaky tests immediately.
- No test data strategy: Tests that depend on shared mutable data or production databases are fragile and unpredictable. Use factories, fixtures, or synthetic data generation.
- Skipping tests entirely: "I'll add tests later" almost always means "I'll never add tests." Write tests alongside your code, not as an afterthought.