Hands-On Software Engineering with Python
上QQ阅读APP看书,第一时间看更新

Test-driven design

Test-Driven Design (TDD), as might be expected from its name, is focused first and foremost on using automated tests of a code base to direct development efforts. The overall process breaks down into the following steps:

  • For each functionality goal (new or enhanced feature) being implemented:
    • Write a new test or set of tests that will fail until the code being tested meets whatever contract and expectations are being tested.
    • Assure that the new test(s) fail, as expected, for the reasons expected, and don't raise any other failures.
    • Write code that passes the new test(s). It may be horribly kludgy and inelegant initially, but this doesn't matter as long as it meets the requirements embedded in the test(s).
    • Refine and/or re-factor the new code as needed, retesting to assure that the tests still pass, moving it to an appropriate location in the code base if necessary, and generally making sure that it meets whatever other standards and expectations are present for the code base as a whole.
  • Run all tests to prove that the new code still passes the new tests, and that no other tests fail as a result of the new code.

TDD offers some obvious benefits as a process:

  • All code in a system will be tested, and have a full suite of regression tests, at a minimum
  • Since the primary goal of writing the code is just to pass the tests created for it, code will frequently be just enough to achieve that, which usually results in smaller, and easier-to-manage code bases
  • Similarly, TDD code tends to be more modular, which is almost always a good thing, and in turn that generally lends itself to better architecture, which also contributes to more manageable code

The main trade-off, also obviously, is that the test suites have to be created and maintained. They will grow as the system grows, and will take longer and longer periods of time to execute, though significant increases will (hopefully) take a while before they manifest. Creation and maintenance of test suites take time, and is a discipline all to itself—some argue that writing good tests is an art form, even, and there's a fair amount of truth to that. On top of that, there's a tendency to look for the wrong sort of metrics to show how well tests perform: metrics such as code coverage, or even just the number of individual test cases, which indicate nothing about the quality of the tests.