EXtreme Programming: Test-First Copyright Rick Mugridge 2001 1 Test-First Programming Rick Mugridge...
Transcript of EXtreme Programming: Test-First Copyright Rick Mugridge 2001 1 Test-First Programming Rick Mugridge...
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 1
Test-First Programming
Rick MugridgeDepartment of Computer Science
University of Auckland
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 2
Test-First Programming• Test-First Programming is one of several synergistic practices of
eXtreme Programming• It can be applied alone. A good first step towards XP
• Who hates testing?• Executable tests• JUnit• It's a matter of timing• Where does that get us?• Limits of testing• An enabling practice• Testing & Refactoring• Difficult things to test
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 3
Who hates testing? • Many programmers enjoy programming but dislike testing and
put it off as long as possible. Do you? • A test is likely to show that you've made a mistake
• Not what you want to know• Who wants to stop coding (and thus "progress") while you track
down a bug and fix it? • Remember the last time you fixed a bug in a piece of code that
you'd written weeks before• Tracking the source• Understanding the code (again)• Fix it• Check it
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 4
Who hates testing?• On average, 16% of bug fixes introduce other bugs• Painful manual effort of going through each test and checking
the results against what's expected• Boring job, easy to miss errors• Easy to avoid after a "trivial" change
• Projects are often rushed towards the end• Testing tends to be done superficially• Customer ends up with an extra job
• So:• We all makes mistakes• We know that testing is needed• What can be done to avoid the negatives of testing?
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 5
Executable tests• Avoid the tedium of manual testing• Turn testing into coding, which is more enjoyable. • Tests are written in code, with expected results included in each
test case• All the tests can be run as often as we like, with little effort• We're simply informed of the ones that failed.
• When we make a change, we can run all the tests• We get immediate feedback if we've broken other code, so we
can fix it now, rather than once we've forgotten the details • We can get pleasure from seeing all the tests pass
• This adds to a sense of closure• Closure helps the programmer to have increased confidence
that they have finished a piece of work
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 6
Executable tests• Consider when using a new API, or one that you expect to
change• Write unit tests to check your understanding of those parts of
the API that you plan to use• Those tests can be run to pick up any changes in new
versions.• JUnit (www.junit.org) is an excellent framework for writing
test cases in Java• Developed by Kent Beck and Erich Gamma• There are versions of this framework for many other
programming languages, including C#, Delphi, Visual Basic and C
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 7
JUnit: TestStackimport junit.framework.*;
public class TestStack extends TestCase {public static void main(String[] args) {
junit.swingui.TestRunner.run(TestStack.class);}
protected Stack stack;protected Object element1, element2;
public TestStack(String name) {super(name);
}public void setUp() {
stack = new Stack();element1 = "1";element2 = "2";
}
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 8
TestStackpublic void testEmpty() {
assertTrue("Stack should be empty",stack.isEmpty());}public void testNonEmpty() {
stack.push(element1);assertTrue("Stack should not be empty",!stack.isEmpty());
}public void testTop() {
stack.push(element1);try {
assertEquals(element1,stack.top());} catch (StackException se) {
fail("Top access should have suceeded.");}assertTrue("Stack should not be empty",!stack.isEmpty());
}
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 9
TestStackpublic void testPop() {
stack.push(element1);try {
stack.pop();} catch (StackException se) {
fail("Pop should have suceeded.");}assertTrue("Stack should be empty",stack.isEmpty());
}public void testFailedTop() {
try {stack.top();fail("Top access should not have suceeded.");
} catch (StackException se) {}
}
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 10
Example: Drawn• Drawing package• Developed through test-first programming
• 1574 lines of Java code• 647 lines are Test classes
• 67 tests• due to inheritance, 86 tests actually run
• Some tests generate MouseEvents to test interaction
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 11
It's a matter of timing• When's the best time to find an error in your code?
• When it's fresh in your mind, when you're thinking about what's required and how to achieve it
• So we want the tests as early as possible. • The earliest possible time to consider testing is just before you
write the code• The approach is very simple:
• Write one or two tests for some small addition of functionality in your program and then write the code
• Then do it again, with a cycle time of minutes.
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 12
It's a matter of timing• Run the test before writing the new code
• Add just enough interface to compile it• This tests our test, as it should fail
• It's often surprising when a test succeeds at this stage• Oops, perhaps I don't understand my code as well as I
thought!• Then write the code and run all the tests• Fix any errors as they arise
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 13
Where does that get us?• We first think about the cases from the point of view of what's
required, rather than how to do it• Our tests help us sort out the interface and what should
happen• As we write a test, we're thinking about the issues, but from
the outside• Specification-based
• As we have no (new) code to break, we don't have any ego in it• So we can invest emotionally in the tests before we then invest
in the code to be tested.
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 14
Where does that get us?• By the time we've written a few tests, we're probably clearer
about what's needed• Then we can focus on how to achieve it, which goes much
faster• When the new and altered code passes all the tests:
• We have much more confidence that we've completed that piece of work, and that we haven't broken anything
• Closure
• The design of the code is affected by the tests• The tests force us to make it testable, which is also inclined to
make it more modular
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 15
Where does that get us?• A major problem for QA people is to retrofit tests for code that
has not been designed with testing in mind• It can be very difficult to tell whether a test has passed• Especially when it's almost impossible to get the right
information back from the program.• Because we continue to add to our suite of test cases, we can
avoid breaking existing code as we change it• The tests end up as an important resource• They also help to define the requirements of each piece in a
precise manner
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 16
Limits of testing• Does this approach eliminate all errors?
• Of course not!• An error can easily arise from a misunderstanding of the
requirements, which gets built into the test and the code• The programmer may well forget an important case in the tests
and also miss it in the code• Or they may misunderstand how library code works and not
pick up the consequent faults.
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 17
Limits of testing• When an error is found, the first step is to add a test case that
duplicates the error• Avoid it being reintroduced
• Once the error is fixed, it makes sense to consider whether there are related errors lurking
• Additional test cases can be added to discover existing errors or ones that may be added in future.
• There is a tradeoff with testing, as it's impossible to test exhaustively
• So it's best to invest in tests for the sorts of errors that you know you make
• A nasty error I've made a few times in Java is to pass a reference to an object and then think that I've passed a copy
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 18
Code review• It has been shown that testing and code review are effective and
complementary techniques for reducing errors• They tend to pick up different sorts of error, so neither is
sufficient alone.• We've shown how testing can be brought into the heart of the
process of programming• The same idea is applied to code review, through pair
programming• Pair programming enhances Test-First programming
• The partner person picks up on misunderstandings, missed test cases, and errors in the code
• The pair are able to discuss it
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 19
An enabling practice• Test-first programming enables and enhances several of the
other practices used in eXtreme Programming.• A comprehensive test suite for a program permits continuous
integration to be applied, as part of a rapid iterative development cycle
• The tests pick up conflicting changes that have been made by different pairs of a team of programmers
• The tests also give confidence that large-scale changes to the software (such as through refactoring) have not broken the code.
• The same approach can be applied to the system as a whole, with acceptance tests defined by the customer and written as automatic tests
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 20
Testing & Refactoring• As code is refactored, some tests may need to be altered to suit
• Eg, if a class or method is split
• As tests are added, they need to be refactored too
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 21
What can't be tested?• Some areas seem difficult to test using executable unit tests
• Database access• Web-based systems• Threads
• Some of these are managed with variants on JUnit, such as HttpUnit
• Some are best managed with Mock objects• For testing database access through JDBC, use (mock)
objects that have the correct interface• Set up expectations as to what will happen
• So errors are signalled as soon as they occur• Can generate exceptions to test the code that is not usually
tested
eXtreme Programming: Test-First Copyright Rick Mugridge 2001 22
To Find Out More• Books
• Kent Beck, Extreme Programming Explained, 1999 Addison-Welsey
• Kent Beck & Martin Fowler, Planning Extreme Programming, 2000
• Ron Jefferies, et al, Extreme Programming Installed, 2000• Robert Martin, James Newkirk, Extreme Programming in
Practice, June 2001• Web sites
• www.junit.org• http://c2.com/cgi/wiki?ExtremeProgrammingRoadmap• www.xprogramming.com• www.xp2001.org
• NZ XP interest group: www.xp.co.nz