Test-Driven Development
An Introduction Mattias Ståhlberg
Debugging
sucks.
Contents
1. What is unit testing?
2. What is test-driven development?
3. Example
4. Writing Testable Code
5. Continuous Integration
6. Recommended reading
What is a Unit Test?
A unit is a class or a set of related functions
Smallest part that makes sense to test
Tests that the unit does what the programmer intended Tests the unit’s public interface
Written contract that the production code must satisfy Requires an automatic unit testing framework
Java Example with JUnit
@Test
public void shouldCalculateAverageSpeed() { Track track = new Track();
track.addPoint(0, 0, 0); track.addPoint(0, 1, 1); track.addPoint(1, 1, 2); track.addPoint(1, 0, 3); track.addPoint(0, 0, 4); assertEquals(1, track.averageSpeed()); } @Test(expected=ArithmeticException.class)
public void averageSpeedShouldThrowExceptionOnZeroDistance() { Track track = new Track();
Advantages of Unit-Tested Code
Gives courage to modify and improve (refactor) the
code
Knowledge that the code works
Problems solved early in the development phase Documents the code
Little or no need for debugging
Reduced need for costly manual testing Saves time and money
Properties of Good Unit Tests
Descriptive name Readable Focused Isolated Automatic Repeatable FastContents
1. What is unit testing?
2. What is test-driven development? 3. Test coverage
4. Visualizing test results
5. Excuses for not testing
6. How to succeed
7. Common pitfalls
8. Recommended reading
What is Test-Driven Development?
Test-driven is more about design than about testing
A design method that renders clean, well-tested code
Short iterations where unit tests, either for
What is Test-Driven Development?
(contd.)
Can also be applied to other types of tests (e.g.
acceptance tests)
Does not imply “no formal testing” Kent Beck:
“Never write a single line of code unless you have a failing automated test”
Development Cycle
1. Create a new automatic test case
2. Run all tests and watch the new one fail
3. Write production code to make the test pass
4. Run all tests and watch them pass
5. Refactor the code, e.g. eliminate duplicated code
6. Start over
Advantages of Test-Driven
Development
Interfaces are tried before they exist more mature
interfaces
More and better tests improved quality
Design and code evolved in small steps less risk, less
integration problems
Less risk to develop functionality “that might be
needed”
Less risk to skip testing when time is short Addictive, stimulating, and great fun
Test-Driven Bug Fixing
1. Create an automatic test that indicates the existence of the bug
2. Locate the bug
3. Fix the bug
Ensures that the automatic tests will detect the problem
Contents
1. What is unit testing?
2. What is test-driven development?
3. Example
4. Writing Testable Code
5. Continuous Integration
6. Recommended reading
Live Demonstration
TDD using Eclipse and JUnit
http://www.eclipse.org
Contents
1. What is unit testing?
2. What is test-driven development?
3. Example
4. Writing Testable Code 5. Continuous Integration
6. Recommended reading
Writing testable code
Use dependency injection Inject interfaces
Favor object composition over class inheritance
Impossible to chose different class hierarchy at test-time but easy to chose different object composition
Favor polymorphism over conditional statements
Leads to smaller and more focused classes, which are easier to test
Writing testable code (contd.)
Avoid global state and singletons
Cannot be replaced at test-time
If you really have to have a singleton: Wrap it in a simple adapter
Avoid non-private static method calls
Cannot be replaced at test-time
Can be wrapped in a simple adapter
Strive for small and focused classes with clear
Google's guide to testable code
http://misko.hevery.com/code-reviewers-guide/
Flaw #1: Constructor does Real Work Flaw #2: Digging into Collaborators
Flaw #3: Brittle Global State & Singletons Flaw #4: Class Does Too Much
Contents
1. What is unit testing?
2. What is test-driven development?
3. Example
4. Writing Testable Code
5. Continuous Integration 6. Recommended reading
Definition of Continuous Integration
“A fully automated and reproducible build, including
testing, that runs many times a day” Martin Fowler (September 2000)
“A software engineering practice in which isolated
changes are immediately tested and reported on when they are added to a larger code base.”
Continuous Integration – Benefits
Allows each developer to integrate daily thus reducing
integration problems
Provides rapid feedback on the “health” of the software If a defect is introduced into the code base, it can be
identified and corrected as soon as possible
Try it out!
Download Hudson from www.hudson-ci.org
Contents
1. What is unit testing?
2. What is test-driven development?
3. Example
4. Writing Testable Code
5. Continuous Integration
6. Recommended reading 7. Conclusions
Recommended Reading
Kent Beck: Test-Driven Development By Example
Andy Hunt, Dave Thomas: Pragmatic Unit Testing in Java
with Junit
Martin Fowler: Refactoring: Improving the Design of
Existing Code
http://www.refactoring.com/
http://xunitpatterns.com/ (also as printed book) http://googletesting.blogspot.com/
Contents
1. What is unit testing?
2. What is test-driven development?
3. Example
4. Writing Testable Code
5. Continuous Integration
6. Recommended reading
Unit testing
Gives courage to refactor and improve Eliminates problems early
Requires discipline
Test-driven development
Is a design method Gives better unit tests
Renders clean code that works Is great fun