test driven development
DESCRIPTION
What are the goals of TDD? What are the problem of TDD?TRANSCRIPT
TDD
Test Driven Development
Software Quality
• A definition in Steve McConnell's Code Complete divides software into two pieces: internal and external quality characteristics.
• External quality characteristics are those parts of a product that face its users, where internal quality characteristics are those that do not.
ISO/IEC 9126-1:2001(E)Internal and External Features
• Functionality
• Reliability
• Usability
• Efficiency
• Maintainability
• Portability
ISO/IEC 9126-1:2001(E)Quality-in-use features
• Effectiveness
• Productivity
• Safety
• Customer Satisfaction
• It is the user’s view of the quality of the software product when it is used in a specific environment and a specific Context-Of-Use.
TDD in summary
A. First we write a test.
B. Then we write code to make the test pass.
C. Then we find the best possible design for what we have - refactoring (Relying on the existing tests to keep us from breaking things while we are at it)
TDD goals
• TDD is a technique for improving the software’s internal quality
Well-written code• Good design• A balanced division of responsibilities• Without duplication (clones)• Smooth evolution• Maintainability
ATDD goals
• Acceptance TDD helps us keep our product’s external quality on track by giving it the correct features and functionality.
• the system should meet what the customer actually need.
Both sides of quality
************************************
• Then, we need to learn how to build the thing right - TDD.
• Also, we need to learn how to build the right thing - ATDD.
TDD and ATDD
Meeting needs with acceptance TDD
Traditional way of adding features
• Requirements – doc
• Implementation – sc• Test design – tc• Developer Test – rep. • Acceptance test
Acceptance TDD• Requirements – doc• Test design – tc• Implementation – sc • Developer Test – rep
• Acceptance test
What is the difference?
• With ATTD we translate a requirement into a set of executable tests and then do the implementation against the tests rather than against the developer’s interpretation of a verbal requirement.
• Rather than working off of arbitrary requirements documents, in acceptance TDD we strive for close collaboration and defining explicit, unambiguous tests that tell us exactly what it means when we say a feature is “done.”
Close relationship
• TDD and acceptance TDD often go hand in hand. On the system level, we run our development process with acceptance TDD; and inside the implementation step of each feature; we employ TDD.
Benefits?
• No more long debugging sessions– Each test case corresponds to a feature of the
system– Test cases support refactoring
• More time for other stuff– Reduce time of debugging sessions– Reduce time fixing bugs– Reduce rework due to misunderstandings
regarding requirements
Benefits?
• Feeling confident with my work– The better your test suite is, the better the
quality of your code and the more confident you can be about any changes you make. The more confident you are about the changes you make, the more changes you dare to make. The more changes you make, the better your internal quality becomes, the easier it is to write tests for your code, and so on. (a virtuous cycle)
Build it right: TDD
• TDD is a development and design technique that helps us build up the system incrementally, knowing that we’re never far from a working baseline.
• A test is our way of taking that next small step.
Build it right: TDD
• Test-Code-Refactor
Build it right: TDD
• Test-Code-Refactor
The term refactoring is used to better communicate that the last step is about transforming the current design toward a better design.
First we write a test
• We are writing a test. Also, we are making design decisions:– We are designing the API—the interface for
accessing the functionality we’re testing.– The test case that we design will be the first
“client” of the functionality that we are going to implement.
– One of the fundamental lessons in designing an interface is that we only evaluate a design effectively and objectively when we try to use it.
Then we write just enough code
• The second step of the TDD cycle is to write just enough code to make the test pass.
• You’re satisfying an explicit, unambiguous requirement expressed by a test.
And then we refactor
• Take a step back, look at our design, and figure out ways of making it better.
• It is all about keeping your software in good health—at all times.
• Refactoring is about applying refactorings on code in a controlled manner
Keeping code healthy with refactoring
• “a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior” : Martin Fowler
Refactoring Example
• Replace Inheritance with Delegation– Motivation: A subclass uses only part of a
superclass interface or does not want to inherit data
– Summary: Create a field for the superclass, adjust methods to delegate to the superclass, and remove the subclassing.
Refactoring Example
Refactoring Example
• Mechanics
1. Create a field in the subclass that refers to an instance of the superclass. Initialize it to this.
2. Change each method defined in the subclass to use the delegate field.
3. Compile and test after changing each method.
Refactoring Example
• Mechanics
4. Remove the subclass declaration and replace the delegate assignment with an assignment to a new object.
5. For each superclass method used by a client, add a simple delegating method.
6. Compile and test.
Refactorings alter internal structure
• Many of the refactorings are very low-level– rename method– Rename variable
• Low-level refactorings are the fundamental building blocks to achieving larger refactorings– Moving the responsibilities around in your
code– Introducing or removing an inheritance
hierarchy
Refactorings preserve behavior
• whatever transformations you apply to the existing code, those transformations should only affect the code’s design and structure—not its externally visible behavior or functionality.– Renaming a method that is part of a class’s
public interface - ???– how can we be sure that our refactorings
haven’t changed the code’s external behavior? - ???
The big picture of developing software in small increments.
The big picture of developing software in small increments.
Acceptance TDD
• Acceptance tests are indicators of the completion of a requirement or feature.
• When all acceptance tests for a requirement or feature are passing, you know you’re done.
Advantages of ATDD
• Close collaboration– Seeing concrete, working software
– Building trust and confidence– Customer in control– Evolving a shared language
• Tests as a shared language– Tests as specification– Specification by example
Tools for test-driven development
• Unit-testing with xUnit– Provides supporting code for writing unit tests,
running them, and reporting the test results.
• Test frameworks for acceptance TDD– Tools for enhancing collaboration in software
development. (Fit and Fitnesse)– They enable customers, testers, and programmers to
learn what their software should do, and to automatically compare that to what it actually does do.
– They compare customers' expectations to actual results.
FitNesse
• FitNesse is a lightweight, open-source framework that makes it easy for software teams to:
– Collaboratively define Acceptance tests -- web pages containing simple tables of inputs and expected outputs.
– Run those tests and see the results
• http://fitnesse.org/
Tools for test-driven development
• Continuous integration and builds– On the one hand, running the full test suite
often takes too long (several minutes—even hours) for a developer to wait for the green bar.
– On the other hand, most of the tests are unlikely to have been affected by the developer’s recent changes
Tools for test-driven development
• Continuous integration and builds
Build servers galore
• Cruise-Control (http://cruisecontrol.sf.net)
• AntHill (http://www.urbancode.com)
• Continuum (http://maven.apache.org/continuum)
• Bamboo (http://www.atlassian.com/software/bamboo/)
Continuous Integration references
• More about the philosophy behind continuous integration and the associated tools:
– http://www.martinfowler.com/articles/continuousIntegration.html.
– http://www.jamesshore.com.
Tools for test-driven development
• Code coverage– In short, code coverage is a measurement of
how thoroughly our automated tests exercise the production code and its source code statements, branches, and expressions.
– http://www.javaranch.com/newsletter/200401/IntroToCodeCoverage.html
Tools for test-driven development
• Code coverage– This can be especially helpful when a team is
just starting to write unit tests or adopting TDD, because it helps pointing out areas of the code base that are not getting tested as thoroughly as other parts of the code.
Tools for test-driven development
• Code coverage tools for java– Cenqua Clover (
http://www.cenqua.com/clover)Cobertura (http://cobertura.sf.net)EMMA (http://emma.sf.net)