Test-Driven Development - UML

An excellent practice promoted by the iterative and agile XP method [BeckOO], and applicable to the UP (as most XP practices are), is test - driven development (TDD) [BeckOO]. It is also known as test - first development. TDD covers more than just unit testing (testing individual components), but this introduction will focus on its application to unit testing individual classes.

In 00 unit testing TDD - style, test code is written before the class to be tested, and the developer writes unit testing code for nearly all production code.

The basic rhythm is to write a little test code, then write a little production code, make it pass the test, then write some more test code, and so forth.

Key Point: The test is written first, imagining the code to be tested is written.

Advantages include:

  1. The unit tests actually get written— Human (or at least programmer) nature is such that avoidance of writing unit tests is very common, if left as an afterthought.

  2. Programmer satisfaction leading to more consistent test writing— This is more important than it sounds for sustainable, enjoyable testing work. If, following the traditional style, a developer first writes the production code, informally debugs it, and then as an afterthought is expected to add unit tests, it doesn't feel satisfying. This is test - last development, also known as Just - this - one - time - I'll - skip - writing - the - test development. It's human psychology. However, if the test is written first, we feel a worthwhile challenge and question in front of us: Can I write code to pass this test? And then, after the code is cut to pass the tests, there is some feeling of accomplishment - meeting a goal. And a very useful goal - an executable, repeatable test. The psychological aspects of development can't be ignored - programming is a human endeavor.

  3. Clarification of detailed interface and behavior— This sounds subtle but it turns out in practice to be a major value of TDD. Consider your state of mind if you write the test for an object first: As you write the test code. you must imagine that the object code exists. For example, if in your test code you write sale.makeLineItem (description,) to test the makeLineltem method (which doesn't exist yet), you must think through the details of the public view of the method - its name, return value, parameters, and behavior. That reflection improves or clarifies the detailed design.

  4. Provable, repeatable, automated verification— Obviously, having hundreds or thousands of unit tests that build up over the weeks provides some meaningful verification of correctness. And because they can be run automatically, it's easy. Over time, as the test base builds from 10 tests to 50 tests to 500 tests, the early, more painful investment in writing tests starts to really feel like it's paying off as the size of the application grows.

  5. The confidence to change things— In TDD, there will eventually be hundreds or thousands of unit tests, and a unit test class for each production class. When a developer needs to change existing code - written by themselves or others - there is a unit test suite that can be run, providing immediate feedback if the change caused an error.

The most popular unit testing framework is the xUnit family (for many languages), available at For Java, the popular version is JUnit. There's also an NUnit for .NET, and so forth. JUnit is integrated into most of the popular Java IDEs, such as Eclipse.

Example

Suppose we are using JUnit and TDD to create the Sale class. Before programming the Sale class, we write a unit testing method in a SaleTestclass that does the following:

  1. Create a Sale— the thing to be tested (also known as the fixture).
  2. Add some line items to it with the makeLineltem method (the makeLineltem method is the public method we wish to test).
  3. Ask for the total, and verify that it is the expected value, using the assert - True method. JUnit will indicate a failure if any assert True statement does not evaluate to true.

Each testing method follows this pattern:

  1. Create the fixture.
  2. Do something to it (some operation that you want to test).
  3. Evaluate that the results are as expected.

A key pointto note is that we do not write all the unit tests for Sale first; rather, we write only one test method, implement the solution in class Sale to make it pass, and then repeat.

To use JUnit, you must create a test class that extends the JUnitTestCase class; your test class inherits various unit testing behaviors.

In JUnit you create a separate testing method for each Sale method that you want to test. In general you will write unit testing methods (perhaps several) for each public method of the Sale class. Exceptions include trivial (and usually auto - generated) get and set methods.

To test method doFoo, it is an idiom to name the testing method testDoFoo.

For example:

public class SaleTest extends TestCase {
// ...
// test the Sale.makeLineltem method public void testMakeLineAeirU) {
// STEP Is CREATE THE FIXTURE
// -this is the object to test
// -it is an idiom to name it 'fixture'
// -it is often defined as an instance field rather than
// a local variable Sale fixture = new SaleO;
// set up supporting objects for the test Money total = new Money ( 7.5 );
Money price = new Money ( 2.5 );
ItemID id = new ItemID ( 1 );
ProductDescriptiondesc = newProductDescription ( id, price, "product 1" );
// STEP 2: EXECUTE THE METHOD TO TEST
// NOTE: We write this code **imagining** there
// is a makeLineltemmethod. This act of imagination
// as we write the test tends to improve or clarify
// our understanding of the detailed interface to
// to the object. Thus TDD has the side - benefit of
// clarifying the detailed object design.
// test makeLineltemsale.makeLineltem (desc, 1 );
sale.makeLineltem ( desc, 2 );
// STEP 3: EVALUATE THE RESULTS
// there could be many assertTrue statements
// for a complex evaluation // verify the total is 7.5 assertTrue (sale.getTotal().equals( total ));

Only after this testMakeLineltem test method is written do we then write the Sale.makeLineltemmethod to pass this test. Hence, the term test - driven or test - first development.

IDE Support for TDD and xUnit

Most IDEs have built - in support for some xUnit tool. For example, Eclipse supports JUnit. JUnit includes a visual cue - if all the tests pass when executed, it displays a green bar. This gave rise to the TDD mantra: Keep the bar green to

Figure 21.1 Support for TDD and JUnit in a popular IDE, Eclipse


All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

UML Topics