Example and Background


Our discussion in this chapter centers on an ordered list class, in which the elements of the list are integers, and the list is maintained in ascending order. Listing 13.1 contains the method signatures for this class (written in Java).

This simple class contains several categories of relatively standard methods, as follows:

  • A constructor (OrderedList) that returns an empty list

  • Methods to insert a new item at the appropriate location and maintain ascending order (add) and to delete an item by value (delete)

  • Methods to return the integer head of the list (head) and the list with the head removed (tail)

  • Methods to return the length of the list (length) and to examine the list to determine the presence or absence of a particular item (member)

  • A method to compare two lists for equality (equals)

Listing 13.1 Method signatures for the ordered list class
 public class OrderedList {   public OrderedList() {}   public boolean member(int v) {...}   public OrderedList add(int v) {...}   public int head() {...}   public int length() {...}   public boolean equals(OrderedList list) {...}   public OrderedList tail() {...}   public OrderedList delete(int v) {...} } 

It is possible to identify a large number of test cases for this class. We design test cases as assertions on the relationship between objects produced by the various list methods. This is a relatively common XP practice because it supports test automation [Beck2000; Beck+1998]. Table 13.1 contains a set of test cases for this class written as Java assertions, sometimes preceded with additional Java code. We do not claim that these test cases constitute adequate testing for this class; our interest here is simply to define a large enough set to be interesting for a discussion of the micro-incremental testing process. (Note that Table 13.1 uses the notation "<1,2>" to denote a list consisting of 1 as the first element and 2 as the second element. Also, Create is a method external to OrderedList that invokes the OrderedList constructor to generate a new, empty list object.) This method is used for the expository purpose of brevity.

Table 13.1. List Test Cases
  Assertion Explanation
1. assert(Create().add(1).head()== 1); Adding 1 to <> and taking the head should return 1.
2. assert(Create().member(1)== false); 1 is not a member of <>.
3. assert(Create().add(1).tail. equals(Create()); Adding 1 to <> produces <1>. Taking the tail of <1> should produce <>.
4.
 OrderedList L = new OrderedList();   L = L.add(1);   assert(L.add(2).head() ==   L.head()); 
L = <1> (after the add on the second line). After adding a 2, returning the head of the list <1,2> should be equal to returning the head of L itself.
5.
 OrderedList L = new OrderedList();   L = L.add(2);   assert(L.add(1).head() == 1); 
L = <2> (after the add on the second line). After adding a 1, returning the head of the list should be equal to 1 (the item just added).
6.
 OrderedList L = new OrderedList();   L = L.add(2);   assert(L.add(1).tail().equals(L)); 
L = <2> (after the add on the second line). After adding a 1, the list is <1,2>; returning the tail is <2>, which is equal to the original list L.
7.
 OrderedList L = new OrderedList();   L = L.add(0);   assert(L.add(1).tail().equals   (L.tail.add(1)); 
L = <0> (after the add on the second line). After adding a 1, the list is <0,1>; returning the tail yields <1>. This is asserted to be equal to L.tail (<>), followed by adding 1 (which yields <1>).
8. assert(Create().add(1).member(1) == true); Adding 1 to <> and then doing a member test on 1 should return true.
9. assert(Create().add(1).member(2) == Create().member(2)); Performing a member test for the existence of 2 in list <1> should be equal to performing a member test for the existence of 2 in <>.
10. assert(Create().add(1).length() == Create().length + 1); Performing a length test on <1> should be 1 greater than a length test on <>.
11. assert(Create().delete(1). equals(Create())); Based on the spec (not provided here), deleting 1 from <> should be a no-op and simply produce <>.
12. assert(Create().add(1).delete(1). equals(Create())); Deleting 1 from <1> should equal <>.
13. assert(Create().add(1).delete(2). equals(Create().delete(2).add(1))); Deleting 2 from <1> should result in <1>. Deleting 2 from <> and subsequently adding 1 should also result in <1>.

In the rest of the chapter, we use this example (both the ordered list class and associated test cases) to explore our two process models for conducting micro-incremental testing. The next section contains a relatively ad hoc model, while the model of the following section involves more extensive test planning before coding.

To clarify the subsequent discussion, we define some basic testing terminology that is consistent with the development cycle discussed previously. We say that a test run is the actual execution of a test case. Test runs are said to be expected-positive whenever it is expected that they will run properly (that is, after the methods have been implemented). Test runs are said to be expected-negative whenever it is expected that they will not run properly (that is, in the second phase, before the methods have been implemented). A test run is said to be successful if its goal is met. That is, an expected-positive test run is successful if it does not reveal a defect; an expected-negative test run is successful if it does reveal a defect. A test run is feasible if it is possible to achieve success when executed, and infeasible if it is impossible to achieve success. For example, if one or more methods referenced by a test case have not been written yet, an expected-positive test run of that test case is infeasible.



Extreme Programming Perspectives
Extreme Programming Perspectives
ISBN: 0201770059
EAN: 2147483647
Year: 2005
Pages: 445

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net