Test-Driven Development Cycle
1. Write the test
It begins with writing a test. In order to write a
test, the developer must understand the specification and the
requirements clearly. This is accomplished through use cases and user
stories. The design document covers all the test scenarios and
exception conditions.
2. Write the code
The next step is to make the test pass by writing the
code. This step forces the programmer to take the perspective of a
client by seeing the code through its interfaces. This is the design
driven part of test-driven development. As part of test calibration,
your code should fail the test meaningfully the first time around.
3. Run the automated tests
The next step is to run the automated test cases and
observe if they pass or fail. If they pass, the programmer can be more
confident that the code meets the test cases as written. If there are
failures, the code did not meet the test cases..
4. Refactor
The final step is the refactoring step and any code
clean-up necessary will occur here. The test cases are then re-run and
observed.
5. Repeat
The cycle will then repeat itself and start with either adding additional functionality or fixing any errors.
Differing styles
There are various ways one can go about using
test-driven development and the most common one is based on the
principles of “Keep It Simple, Stupid” (KISS) and “You Ain’t Gonna Need
It” (YAGNI). This style focuses on writing only the code necessary to
pass the tests. Design and property principles are cast aside in the
name of simplicity and speed. Therefore, any rule can be violated as
long as the tests will pass. This can be unsettling for many at first
but it will allow the programmer to focus only on what is important.
However, the programmer must pay a bigger fee in the refactoring step
of the cycle since the code must be cleaned up to a reasonable level at
this point before the cycle can restart.
Another variation of test-driven development requires
the programmer to first fail the test cases. The idea is to ensure that
the testcase really works and can catch an error. Once this is shown,
the normal cycle will commence. This is one of the more popular
variations and has been coined the “Test-Driven Development Mantra”,
known as red/green/refactor where red means fail and green is pass.
Benefits
Despite the initial requirements, test-driven
development can provide great value to building software better and
faster. It offers more than just simple validation of correctness, but
can also drive the design of a program. By focusing on the test cases
first, one must imagine how the functionality will be used by clients
(in this case, the test cases). Therefore, the programmer is only
concerned with the interface and not the implementation. This benefit
is complementary to Design by Contract as approaches it through test
cases rather than mathematical assertions.
The power test-driven development offers is the
ability to take small steps when required. It allows a programmer to
focus on the task at hand and often the first goal is to make the test
pass. Exceptional cases and error handling are not considered
initially. These extraneous circumstances are implemented after the
main functionality has been achieved. Another advantage is that
test-driven development, when used properly, ensures that all written
code is covered by a test. This can give the programmer a greater level
of trust in the code.
Limitations
Test-driven development cannot work in an environment
where automated testing is not feasible. The technique is immature and
faces a variety of problems:
Graphical user interfaces (GUIs)—although there are proposed partial solutions
Distributed objects (although mock objects can help)
Database schema
Compilers and Interpreters from BNF to production quality implementation
Some artificial intelligence and pattern recognition algorithms
Some genetic algorithms
It is also important to note that test-driven
development only proves correctness of design and functionality
according to the test cases written. An incorrect testcase that does
not meet the specifications will produce incorrect code. Therefore, the
emphasis on correctness and design has shifted to writing test cases
since they are the drivers. As a result, test-driven development is
only as good as the tests are.
|