Content deleted Content added
→Code visibility: Fix link to unit testing section |
Jnestorius (talk | contribs) |
||
(10 intermediate revisions by 6 users not shown) | |||
Line 2:
{{Software development process}}
'''Test-driven development''' ('''TDD''') is a way of writing [[source code|code]] that involves writing an [[test automation|automated]] [[unit testing|unit-level]] [[Test case (software)|test case]] that fails, then writing just enough code to make the test pass, then [[refactoring]] both the test code and the production code, then repeating with another new test case.
Alternative approaches to writing automated tests is to write all of the production code before starting on the test code or to write all of the test code before starting on the production code. With TDD, both are written together, therefore shortening debugging time necessities.<ref>{{Cite journal |last1=Parsa |first1=Saeed |last2=Zakeri-Nasrabadi |first2=Morteza |last3=Turhan |first3=Burak |date=2025-01-01 |title=Testability-driven development: An improvement to the TDD efficiency |url=https://www.sciencedirect.com/science/article/pii/S0920548924000461 |journal=Computer Standards & Interfaces |volume=91 |pages=103877 |doi=10.1016/j.csi.2024.103877 |issn=0920-5489|url-access=subscription }}</ref>
TDD is related to the test-first programming concepts of [[extreme programming]], begun in 1999,<ref name="Cworld92">{{cite web |url=http://www.computerworld.com/softwaretopics/software/appdev/story/0,10801,66192,00.html |title=Extreme Programming |author=Lee Copeland |date=December 2001 |publisher=Computerworld |access-date=January 11, 2011 |archive-url=https://web.archive.org/web/20110605060209/http://www.computerworld.com/s/article/66192/Extreme_Programming?taxonomyId=063 |archive-date=June 5, 2011 |url-status=dead }}</ref> but more recently has created more general interest in its own right.<ref name=Newkirk>Newkirk, JW and Vorontsov, AA. ''Test-Driven Development in Microsoft .NET'', Microsoft Press, 2004.</ref>
Line 72:
In test-driven development, writing tests before implementation raises questions about testing [[access modifiers|private methods]] versus testing only through [[Interface (computing)|public interfaces]]. This choice affects the design of both test code and production code.
===Test isolation===
Test-driven development relies primarily on [[unit testing|unit tests]] for its rapid red-green-refactor cycle. These tests execute quickly by avoiding process boundaries, network connections, or external dependencies. While TDD practitioners also write [[integration testing|integration tests]] to verify component interactions, these slower tests are kept separate from the more frequent unit test runs. Testing multiple integrated modules together also makes it more difficult to identify the source of failures.
When code under development relies on
Since test doubles don't prove the connection to real external components, TDD practitioners supplement unit tests with [[integration testing]] at appropriate levels. To keep execution faster and more reliable, testing is maximized at the unit level while minimizing slower tests at higher levels.
===Keep the unit small===
Line 125 ⟶ 104:
* Dependencies between test cases. A test suite where test cases are dependent upon each other is brittle and complex. Execution order should not be presumed. Basic refactoring of the initial test cases or structure of the UUT causes a spiral of increasingly pervasive impacts in associated tests.
* Interdependent tests. Interdependent tests can cause cascading false negatives. A failure in an early test case breaks a later test case even if no actual fault exists in the UUT, increasing defect analysis and debug efforts.
* Testing precise execution
* Building "all-knowing oracles". An oracle that inspects more than necessary is more expensive and brittle over time. This very common error is dangerous because it causes a subtle but pervasive time sink across the complex project.<ref name="pathfindersolns.com">{{YouTube| id=0BWSms3J40Y| title=Test-Driven Development (TDD) for Complex Systems Introduction}} by Pathfinder Solutions</ref>{{Clarify|reason=needs better explanation, what is an all-knowing oracle? needs better tone, more factual|date=February 2022}}
* Testing implementation details.
Line 171 ⟶ 150:
Creating and managing the [[Software architecture|architecture]] of test software within a complex system is just as important as the core product architecture. Test drivers interact with the UUT, [[test double]]s and the unit test framework.<ref name="Pathfinder Solutions" />
== Advantages and Disadvantages
=== Advantages ===
Line 194 ⟶ 173:
# '''Increased Code Volume''': Implementing TDD can result in a larger codebase as tests add to the total amount of code written.
# '''False Security from Tests''': A large number of passing tests can sometimes give a misleading sense of security regarding the code's robustness.<ref>{{Cite journal |last1=Parsa |first1=Saeed |last2=Zakeri-Nasrabadi |first2=Morteza |last3=Turhan |first3=Burak |date=2025-01-01 |title=Testability-driven development: An improvement to the TDD efficiency |url=https://www.sciencedirect.com/science/article/pii/S0920548924000461 |journal=Computer Standards & Interfaces |volume=91 |pages=103877 |doi=10.1016/j.csi.2024.103877 |issn=0920-5489|url-access=subscription }}</ref>
# '''Maintenance Overheads''': Maintaining a large suite of tests can add overhead to the development process.
# '''Time-Consuming Test Processes''': Writing and maintaining tests can be time-consuming.
# '''Testing Environment Set-Up''': TDD requires setting up and maintaining a suitable testing environment.
# '''Learning Curve''': It takes time and effort to become proficient in TDD practices.
# '''Overcomplication''':
# '''Neglect of Overall Design''': Focusing too narrowly on passing tests can sometimes lead to neglect of the bigger picture in software design.
=== Benefits ===
Line 332 ⟶ 310:
* [[Self-testing code]]
* [[Software testing]]
* [[Transformation Priority Premise]]
* [[Unit testing]]
|