Test Driven Development (TDD) is a software development process that relies on the repetition of short development cycles called "red-green-refactor" cycles. Each cycle begins with writing an automated test that defines a new function or improves an existing function. The test is then run to verify it fails ("red"). Code is then written to implement the new function or change ("green"). Finally, code is refactored to improve design and readability without changing functionality. TDD results in code that is well-tested, loosely coupled, and easy to maintain or modify. Popular TDD tools include JUnit, NUnit, and PHPUnit.
How to Troubleshoot Apps for the Modern Connected Worker
TDD - Learn Test Driven Development Fundamentals and Benefits
1. TDD – Test Driven Development
Quang Nguyen Ba
Software
www.hyperlogy.com
2. Contents
What is Test Driven Development (TDD)
Red/Green/Refactor Concepts
TDD Programming Tasks
TDD Benefits
.NET Examples
TDD Tools
www.hyperlogy.com
3. Test Driven Development
Developed by Kend Beck
Related to Test First
programming concepts of XP
Goals
– Clean code: no less, no more,
no duplicate.
– Automated Test
– Agile
www.hyperlogy.com
5. Test Driven Development
TDD Rules
– Write new code only if you first have a failing
automated test.
– Eliminate duplication.
Test Types
– Programmer Tests: Technical facing or Unit test
• Tests are created by developer
– Customer Tests: Business facing, acceptance test
• Test are created by customer
www.hyperlogy.com
6. Red/Green/Refactor
Red
– write a little test that doesn’t work, perhaps
doesn’t even compile at first
Green
– make the test work quickly, committing whatever
sins necessary in the process
Refactor
– eliminate all the duplication created in just
getting the test to work
www.hyperlogy.com
7. TDD Programming Tasks
1. Write the test code.
2. Compile the test code.
(It should fail because you haven’t implemented anything
yet.)
3. Implement just enough to compile.
4. Run the test and see it fail.
5. Implement just enough to make the test pass.
6. Run the test and see it pass.
7. Refactor for clarity and to eliminate duplication.
8. Repeat from the top.
www.hyperlogy.com
8. TDD Benefits
The suite of unit tests provides constant
feedback that each component is still
working.
The unit tests act as documentation that
cannot go out-of-date
When the test passes and the production
code is refactored to remove duplication, it is
clear that the code is finished, and the
developer can move on to a new test.
www.hyperlogy.com
9. TDD Benefits
Test-driven development forces critical
analysis and design
The software tends to be better designed,
that is, loosely coupled and easily
maintainable
Reduced debugging time!
Reduced manual testing time
Continuous Integration
www.hyperlogy.com
10. TDD Example
Unbounded Stack
– Push: inserts an element onto the top
– Pop: removes the topmost element and returns it
– Top: operation returns the topmost element but
does not remove it from the Stack
– IsEmpty: returns true when there are no elements on
the Stack
www.hyperlogy.com
11. Unbounded Stack Test Cases
1. Create a Stack and verify that IsEmpty is true.
2. Push a single object on the Stack and verify that IsEmpty is false.
3. Push a single object, Pop the object, and verify that IsEmpty is true.
4. Push a single object, remembering what it is; Pop the object, and verify
that the two objects are equal.
5. Push three objects, remembering what they are; Pop each one, and
verify that they are removed in the correct order.
6. Pop a Stack that has no elements.
7. Push a single object and then call Top. Verify that IsEmpty is false.
www.hyperlogy.com
12. Unbounded Stack Test List
8. Push a single object, remembering what it is; and then call Top. Verify
that the object that is returned is the same as the one that was pushed.
9. Push multiple objects, remembering what they are; call Top, and verify
that the last item pushed is equal to the one returned by Top.
10. Push one object and call Top repeatedly, comparing what is returned to
what was pushed.
11. Call Top on a Stack with no elements.
12. Push null onto the Stack and verify that IsEmpty is false.
13. Push null onto the Stack, Pop the Stack, and verify that the value
returned is null.
14. Push null onto the Stack, call Top, and verify that the value returned is
null.
www.hyperlogy.com
The first rule is straightforward: don’t write code without having a failing automated test because the tests embody the requirements that the code must satisfy, as stated in the Introduction. If there is no requirement (that is, test), there is no need to implement anything. This rule prevents us from implementing functionality that is not tested and not needed in the solution.The second rule states that no code should be duplicated in the program. Code duplication is the epitome of bad software design; it leads to inconsistency problems and a reduced level of confidence in the program over time as people forget where the duplications are. If there is code duplication, it is the programmer’s job to remove it when it is seen. (In Extreme Programming [XP], this rule is called “Once and Only Once!”)
Test ListIn Kent Beck’s book, Test-Driven Development: By Example (Addison-Wesley, 2003), he describes a test list. When starting a new task or feature, you need to brainstorm a list of tests. As you think about these tests, write them down. In addition to describing the requirements unambiguously, this test list also indicates the scope of the activity and is the most complete definition of the completion criteria. How long should you spend doing this? For most tasks that end up taking about 4 hours, we spend about 15–20 minutes doing this activity. If the scope of the list is too large, the list can be the basis for further estimation.
Test-driven development forces critical analysis and design because the developer cannot create the production code without truly understanding what the desired result should be and how to test it.The software tends to be better designed, that is, loosely coupled and easily maintainable, because the developer is free to make design decisions and refactor at any time with confidence that the software is still working. This confidence is gained by running the tests. The need for a design pattern may emerge, and the code can be changed at that time. The test suite acts as a regression safety net on bugs: If a bug is found, the developer should create a test to reveal the bug and then modify the production code so that the bug goes away and all other tests still pass. On each successive test run, all previous bug fixes are verified.
Choosing the First TestThere are differing opinions about which test to choose first. One says that you should choose the simplest test that gets you started and solves a small piece of the problem. Another says that you should choose a test that describes the essence of what you are trying to accomplish. For example, looking at the test list in the previous section, the simplest test is the first one: Create an empty Stack and verify that IsEmpty is true. This operation looks as if it would be easy to implement, but it does not provide a great deal of useful feedback when developing a Stack because the IsEmpty function is a supporting function.