Key Concepts
Testing is not optional. The question is when and how — earlier testing is orders of magnitude cheaper.
Unit Testing
Test individual functions/methods in isolation. Fast, cheap, runs on every commit.
Integration Testing
Test that components work correctly together — APIs, databases, services.
System Testing
Test the complete integrated system against requirements. End-to-end, black-box.
Test-Driven Development (TDD)
Red → Green → Refactor. Write the test FIRST. Then write code to make it pass.
User Acceptance Testing
Testing by end-users to confirm the system meets their needs. Alpha, Beta, A/B testing.
Concept Deep Dives
Click each concept to expand — real examples, diagrams, pros & cons.
Unit Testing
When to Use
Always — every function with meaningful logic should have unit tests.
Real-World Example
Testing a calculateTax(amount, rate) function with multiple inputs: 0%, 10%, negative values, edge cases.
✓ Advantages
- Fast to run
- Pinpoints exact failure location
- No external dependencies needed
⚠ Watch Out
- Doesn't test component interactions
- Mocks can hide integration bugs
calculateTax(100, 0.10) → 10calculateTax(0, 0.10) → 0calculateTax(-1, 0.10) → raises ValueErrorIntegration Testing
When to Use
After unit tests — test the contracts between components.
Real-World Example
Testing that the login controller correctly calls the auth service which correctly queries the database.
✓ Advantages
- Catches interface mismatches
- Tests real component interaction
- Closer to production behavior
⚠ Watch Out
- Slower than unit tests
- Harder to set up (needs running services)
- Flaky if using real external services
System Testing
When to Use
After integration — test the whole system as users will use it.
Real-World Example
Testing a checkout flow from product selection → cart → payment → confirmation → email — in a staging environment.
✓ Advantages
- Tests real user scenarios
- Validates against requirements
- Finds emergent defects
⚠ Watch Out
- Slow and expensive
- Hard to isolate failures
- Environment setup complexity
Test-Driven Development (TDD)
When to Use
Feature development where you want clean design + high confidence.
Real-World Example
'I need to parse a JWT' → write test for valid/invalid/expired tokens FIRST → then write the parser.
✓ Advantages
- Forces clear interface design upfront
- High test coverage by default
- Refactoring confidence
⚠ Watch Out
- Slower initial velocity
- Requires discipline
- Hard to apply to UI or legacy code
User Acceptance Testing
When to Use
Before final release — validate with real users in real environments.
Real-World Example
Beta testing: ship to 1% of users, monitor for crashes and feedback before 100% rollout.
✓ Advantages
- Real user validation
- Catches usability issues
- Business sign-off
⚠ Watch Out
- Expensive and slow to arrange
- Users may not test edge cases
- Hard to reproduce bugs
Quick Reference
- 1Testing is the primary quality assurance technique — validates that system meets requirements.
- 2Development testing: unit, component, system. Done by developers during development.
- 3Unit testing: test individual program units in isolation. Automated, fast.
- 4Test-driven development: write tests before code. Red-Green-Refactor cycle.
- 5Release testing: independent team validates the system before release.
- 6User testing: alpha (internal), beta (external), acceptance testing.
- 7Inspections and reviews complement testing — find different types of defects.
From the Book & Beyond
Case Study — Testing the Weather Station (and a Famous Quote)
The chapter opens with Dijkstra's classic warning: "Testing can only show the presence of errors, not their absence." Then Sommerville makes it concrete with the wilderness weather station from Chapter 7. To unit-test the WeatherStation object, you test state sequences from its state model — like Running → Collecting → Running → Summarizing → Transmitting → Running. And inspections earn surprising respect: Fagan (1976) reported that informal program inspections can detect more than 60% of a program's errors, and the Cleanroom process claims over 90% — because unlike testing, inspections aren't fooled by one error masking another.
2026 Perspective — AI Writes the Tests, Production Is the Lab
Sommerville says automatic test-case generation is impossible because someone must know the expected output. In 2026, LLM assistants like Copilot and Claude generate plausible unit tests from your code — but the oracle problem still stands: a human must judge whether the expected results are right. Property-based testing (Hypothesis, fast-check) attacks it differently, checking invariants across thousands of random inputs — equivalence partitioning on autopilot. And testing didn't stop at release: teams now "shift left" with tests in CI on every commit, then keep testing in production with feature flags and canary releases that expose new code to 1% of users first.
Quiz — Test Yourself
Think through your answer first, then reveal.