Test-driven development (TDD) is a software development process concerning the creation of concise, clean and testable code. The core principle of TDD asserts that testing should be done as part of the development process to drive the software’s progression (Beck, 2004). More specifically, tests should be created for isolated functionality prior to the implementation of code for that functionality (Erdogmus, Morisio, Torchiano, 2005). The TDD approach guides developers along a series of iterative steps to optimise the development and testing processes. The first step stipulates that a simple test must be established for an isolated requirement. Such a test will inevitably fail to compile due to the absence of production code. However, the process continues with the development of code to enable the test to compile; producing a fail result. Once the test compiles, the production code for the requirement in question can be fully implemented, so as to pass the test. The final stage of the TDD process involves the refactoring of both the test and production code in an attempt to reduce duplicate code and ensure that the existing design is optimal (Beck, 2004). In addition, as the code is refactored, the test should be continually run to guarantee that the code continues to behave as expected. This cycle is then repeated for every required function to continue the development process. For each function the developer must create a test, get that test to fail, write code to pass the test and then refactor the implemented code, whilst ensuring that the test, and all previously established tests, are still passed (see Figure 1.1 for a simplified diagrammatic explanation).
The question naturally arises, what functionality should be tested? I.e. how complex should each test be? In answer to this, TDD dictates that tests should be as simple as possible, focusing on a discrete behaviour. The principle being to ensure that the each behaviour is tested in isolation (Astels, 2003). Subsequently, TDD implies that tests should be designed to minimise dependencies. Methods or components outside the context of the behaviour in question should not be considered by the test. This therefore, ensures that the developed section of code behaves as expected in isolation (Janzen, Saiedian, 2008). With regards to the definition of the boundaries surrounding a particular test, design patterns known as testables (such as mocks, stubs and fakes), can be utilised to isolate the behaviour being tested, ensuring the test is kept as simple as possible (Astels, 2003).
Thus far, this paper has considered TDD to be a development process employed at the genesis of a project to ensure the program code is testable from the bottom up. However, TDD can also be applied part way through a project, or indeed to legacy code. Under such circumstances, TDD can be utilised to great benefit, via the refactoring of existing code and the introduction of numerous function specific tests (Linnamaa, 2008). However, the implementation of TDD to an existing project does generate additional risks, particularly if the code being altered has no pre-existing testing procedures. Nevertheless, to deliver the benefits associated with TDD, this technical debt must be paid.
However, there are also a number of disadvantages associated with TDD procedures. Most notably, the use of TDD can greatly slow the development process by imposing strict testing procedures (Erdogmus, Morisio, Torchiano, 2005). Subsequently, the costs associated with the project can be significantly escalated due to the delay in development. Additionally, TDD places a significant burden on the developer in terms of maintaining the numerous tests since each test will require maintenance as the code being tested develops and changes (Linnamaa, 2008). This requirement, of continuously tweaking the test code to accommodate for changes in the program code, further delays the development process. Moreover, many projects evolve during the course of their development; at the beginning of a project the solution is not always foreseeable. Consequently, developers will be forced to redo tests, creating additional time delays (stackoverflow.com). Furthermore, many dependencies between classes and methods need to be broken to create testable code using TDD. For larger, more complex projects this breaking of dependencies to isolate individual test cases can be extremely difficult and may in-fact add to the overall complexity of the project (Erdogmus, Morisio, Torchiano, 2005)
In summary, it is clear that there are a number of distinct drawbacks which can arise from the implementation of TDD, particularly with regard to the amount of time invested in the development phase. Nevertheless, despite these undesirable characteristics, TDD offers a logical and structured design approach, forcing developers to focus on the task at hand. Implicitly, TDD encourages developers to produce simple, maintainable code. TDD is therefore an extremely effective development style, helping to ensure the development process remains structured and agile.
APPENDIX:
Figure 1.1:
REFERENCES:
S. W. Ambler, (2008), Introduction to Test Driven Design (TDD), AgileData, accessed on the 24.11.2010, http://www.agiledata.org/essays/tdd.html
S. W. Ambler, (2007), Test-Driven Development of Relational Databases, IEEE Computer Society, Vol. 24, No. 3, p. 37 – 43.
D. Astels, (2003), Test-Driven Development: A Practical Guide, Prentice Hall PTR.
K. Beck, (2004), Test-Driven Development: By Example, Pearson Education, 5th Edition.
H. Erdogmus, M. Morisio, M. Torchiano, (2005), On the Effectiveness of the Test-First Approach to Programming, IEEE Transactions on Software Engineering, IEEE Computer Society, Vol.: 31, Iss. 3, p. 226 – 237.
D. S. Janzen, H. Saiedian, (2005), Test-Driven Development Concepts, taxonomy, and Future Direction, IEEE Computer Scoiety, VOl. 38, ISS. 9, p. 43 – 50
D. S. Janzen, H. Saiedian, (2008), Does Test-Driven Development Really Improve Software Design Quality? IEE Software, Vol. 25, no. 2, p. 77 – 84.
L. Linnamaa, (2008), Test-Driven Development, University of Helsinki Computer Science Department,http://www.cs.helsinki.fi/u/linnamaa/linnamaa-Test-Driven-Development-final.pdf
R. C. Martin, (2007), Professionalism and Test-Driven Development, IEEE Computer Society, Vol. 24, No. 3. p. 32 - 36.
M. Natté, (2009), Introduction to Unit Testing, .Net blogs, accessed on 26.11.2010, http://martijnnatte.wordpress.com/2009/07/09/introduction-to-unit-testing/
stackoverflow.com, accessed on 26.11.2010,
http://stackoverflow.com/questions/64333/disadvantages-of-test-driven-development
No comments:
Post a Comment