Test-Driven Development
Test-driven development is a programming practice that alternates a failing automated test, the code needed to pass it, and refactoring. Each short cycle defines one behavior and leaves a repeatable check that protects it.
itSoftware engineering | OpenSkills.info
Course pathWalk it in order
Look it upDip in anytime
Go furtherLeaves this page
Don't Panic
Test-Driven Development
Test-driven development, or TDD, is programming arranged around evidence instead of hopeful nodding at a diff. You write one small automated test for behavior that does not exist yet, watch it fail for the right reason, make it pass, then improve the structure while the tests guard the exits. The loop has the memorable traffic-light names red, green, refactor, because software people are apparently comforted by colors.
The important bit is not that tests appear before code in a ceremonial queue. Red proves that the new test can notice the missing behavior. A failure caused by an import, a typo, or a broken fixture is merely a different sort of red flag. Green restores a working baseline after a focused code change. Refactor changes internal structure while the observed behavior stays put. Each step answers a different question, which is far more useful than treating one large passing suite as a decorative houseplant.
A test list keeps the next decision small. Start with a normal case that establishes the public interface. Add another example when the first one passes too cheaply. Then use boundary and error cases to expose rules nobody had to decide earlier. The list can change as the code teaches you something, which is precisely why writing twenty tests before running one is less heroic than it sounds.
Tests also reveal design trouble. Awkward setup, hidden global state, and a crowd of collaborators are not merely irritating obstacles between you and a green check mark. They can show that the production boundary is carrying too much coupling. Prefer an assertion about a returned value, durable state, or required message over an assertion that a private helper performed its little dance in the approved sequence.
A test double is useful when a real collaborator is slow, unstable, or difficult to provoke. It makes one boundary controllable, but it cannot prove that the real service behaves the same way. That is why TDD lives beside integration checks, exploratory work, security analysis, performance testing, and operational validation. No single test suite is a wizard, even when it owns a very confident runner.
Continue with the intro for the full map of the cycle and its limits. Use the slides when you want the relationships at a glance, the cheatsheet when a red result needs diagnosis, and the practice exercise when this stops being a sensible theory and starts producing evidence in a local program.
Where this skill leads
Relevant careers
See how this topic contributes to broader role-level skill maps.
Sources
- https://agilealliance.org/glossary/tdd/
Supports
- Definition and repeated test-code-refactor rules of test-driven development
- Expected benefits with explicit limits on empirical confirmation
- Individual and team pitfalls, skill progression, and historical milestones from 1976 through 2006
- Quiz answers about the cycle, scope, and refactoring
- https://newsletter.kentbeck.com/p/canon-tdd
Supports
- Canonical test-list, one-test, passing-code, refactoring sequence
- Reasons to keep the test list revisable and avoid a speculative batch of runnable tests
- SUnit in 1994 and the October 1995 OOPSLA demonstration
- Quiz answers about intended red, test sequencing, and new discoveries during green
- https://martinfowler.com/bliki/TestDrivenDevelopment.html
Supports
- Red-green-refactor cycle, test-list sequencing, and interface-first design pressure
- Refactoring as an essential step rather than an optional cleanup phase in practice
- Quiz answers about green, refactoring, and test sequence
- https://martinfowler.com/bliki/SelfTestingCode.html
Supports
- Distinction between TDD and a self-testing regression suite
- Frequent automated execution and test-first defect fixing
- Relationship between self-testing code and continuous integration
- https://martinfowler.com/articles/mocksArentStubs.html
Supports
- Distinction between stubs, mocks, state verification, and behavior verification
- Limits and design consequences of interaction-focused tests
- Quiz answers about observable behavior and real-provider evidence
- https://martinfowler.com/articles/practical-test-pyramid.html
Supports
- Selecting focused tests and using real boundaries where their behavior carries the risk
- Quiz answer about database-specific constraints
- https://agilealliance.org/glossary/refactoring/
Supports
- Refactoring improves internal structure while preserving external behavior
- Quiz answer about structural change under a green suite
- https://gds-way.digital.cabinet-office.gov.uk/standards/test-driven-development.html
Supports
- Canonical red-green-refactor inner loop and fast feedback
- Use of another feedback mechanism when canonical TDD does not fit the uncertainty
- Reference-link rationale and quiz answer about exploratory work
- https://docs.pytest.org/en/stable/explanation/fixtures.html
Supports
- Fixtures provide reliable test context and safe teardown
- Order-dependent failures as evidence to inspect state isolation and cleanup
- https://github.com/sindresorhus/awesome
Supports
- The index identifies awesome-testing as the curated software-testing list
- https://github.com/TheJambo/awesome-testing
Supports
- Service virtualization section identifies WireMock and MockServer as testing ecosystem tools
- https://wiremock.org/docs/
Supports
- HTTP response stubbing, request matching, fault simulation, and verification
- Awesome Links rationale and quiz answer about controlled collaborators
- https://www.mock-server.com/mock_server/getting_started.html
Supports
- Expectation setup, system execution, recorded traffic, and request verification
- Awesome Links rationale
- https://junit.org/junit5/docs/current/user-guide/
Supports
- JUnit assertions, lifecycle hooks, test discovery, and parameterized tests
- Landscape placement, open-source licensing, and free availability
- https://docs.pytest.org/en/stable/contents.html
Supports
- pytest assertions, fixtures, parametrization, selection, and reporting
- Landscape placement, open-source licensing, and free availability
- https://jestjs.io/docs/getting-started
Supports
- Jest matchers, setup and teardown, mock functions, focused execution, and test reporting
- Landscape placement, open-source licensing, and free availability
- https://vitest.dev/guide/
Supports
- Vitest matchers, mocks, focused runs, Vite configuration, and browser mode
- Landscape placement, open-source licensing, and free availability
- https://docs.nunit.org/
Supports
- NUnit assertions, test cases, setup, teardown, and runner integration
- Landscape placement, open-source licensing, and free availability
- https://xunit.net/docs/getting-started/v3/getting-started
Supports
- xUnit.net runner, facts, theories, assertions, and per-test execution
- Landscape placement, open-source licensing, and free availability
- https://rspec.info/features/3-13/rspec-core/
Supports
- RSpec executable examples, expectations, shared context, controlled collaborators, and focused runs
- Landscape placement, open-source licensing, and free availability
- https://docs.phpunit.de/
Supports
- PHPUnit assertions, fixtures, data providers, and test doubles
- Landscape placement, open-source licensing, and free availability
- https://google.github.io/googletest/
Supports
- GoogleTest assertions, fixtures, parameterized tests, and death tests
- Landscape placement, open-source licensing, and free availability
- https://agilealliance.org/glossary/atdd/
Supports
- ATDD definition and adoption through Fit and FitNesse in 2003 to 2004
- Timeline milestone and relationship between TDD and acceptance examples
- https://dannorth.net/blog/introducing-bdd/
Supports
- September 2006 publication introducing BDD and its teaching motivation
- Timeline milestone and BDD relationship to TDD
