Test-driven development

From Citizendium
Revision as of 07:54, 12 May 2010 by imported>Tom Morris (→‎The process)
Jump to navigation Jump to search
This article is developing and not approved.
Main Article
Discussion
Related Articles  [?]
Bibliography  [?]
External Links  [?]
Citable Version  [?]
 
This editable Main Article is under development and subject to a disclaimer.

Test-driven development (or TDD) is a software development practice where a programmer creates a failing test case before writing the implementation, then stopping when the test passes. Advocates of test-driven development claim that it increases productivity and reduce the amount of time that needs to be spent debugging code.

The process

  1. Write a test that specifies the expected behaviour of a unit of code
  2. Run the test suite and make sure that the new test fails
  3. Write the code to implement the feature
  4. Run the test suite and make sure that all the tests pass
  5. Refactor the code, then start the process again.

What makes this process different from other software development processes is the importance of short iterations - each test should ideally test one particular method or behaviour. At the end of the development process, the software should have hundreds or thousands of tests. Each test is an iterative improvement on the previous step, and should help the developer figure out exactly what the problem is when it fails.

In unit test frameworks, typically the following set of assertions are available:

  • equality - expect that the function should return this value
  • greater than/less than
  • type - that the returned object is a string (especially in languages without type declaration)
  • whether or not exceptions have been raised - you may pass in an error which should cause the software to throw an exception and then check to make sure that exception has been thrown
  • 'almost equals' - that the result is equal to the expected result within a defined margin of error

It can get difficult to write unit tests for more complex pieces of software: mocking and stubbing are often required to simulate processes with external side-effects (for instance, procedures that talk to the filesystem, network or database which are prone to the file not existing, the network being down or the database not being available). Writing tests for concurrent operations is also difficult because of the nondeterministic nature of thread scheduling. This has led to the development of tools like Concutest, ConTest and xrayspecs.

Benefits

According to a 2005 report, the use of unit testing and a test-driven development strategy makes programmers more productive and "the minimum quality increased linearly with the number of programmer tests, independent of the development strategy employed"[1]

One other significant benefit for the use of test-driven development is that when users deploy software on an unforeseen platform, the test suite can be run to determine what errors are occurring, and to help developers figure out what to do to solve the problem.

References

  1. Erdogmus, H. "On the Effectiveness of Test-first Approach to Programming", Proceedings of the IEEE Transactions on Software Engineering, 31(1), January 2005.