Section 23.2. Testing Ordered Lists


23.2. Testing Ordered Lists

We now look at the fixture for the discount group test from Section 5.2 on p. 34, as shown again in Figure 23.3. In this case, we make use of order, an extra column in the table.

Figure 23.3. RowFixture Table That Tests the Order Explicitly

DiscountGroupOrderedList

order

future value

max owing

min purchase

discount percent

1

low

0.00

0.00

0

2

low

0.00

2000.00

3

3

medium

500.00

600.00

3

4

medium

0.00

500.00

5

5

high

2000.00

2000.00

10


The fixture class DiscountGroupOrderedList is shown in Listing 23.3. As a subclass of fit.RowFixture, this class defines the methods query() and getTargetClass().

Listing 23.3. DiscountGroupOrderedList.java
 1 public class DiscountGroupOrderedList extends fit.RowFixture { 2    public Class getTargetClass() { 3       return OrderedDiscountGroup.class; 4    } 5    public Object[] query() throws Exception { 6       DiscountGroup[] groups = DiscountGroup.getElements(); 7       OrderedDiscountGroup[] ordered = 8               new OrderedDiscountGroup[groups.length]; 9       for (int i = 0; i < groups.length; i++) { 10         DiscountGroup g = groups[i]; 11         ordered[i] = new OrderedDiscountGroup(i+1, 12              g.getFutureValue(),g.getMaxOwing(), 13              g.getMinPurchase(),g.getDiscountPercent()); 14         } 15      return ordered; 16   } 17 } 

Method getTargetClass() of the fixture (line 2 in Listing 23.3) returns the class of the elements of the list, OrderedDiscountGroup. RowFixture uses the returned Class to check that instance variables correspond to each of the header labels in Figure 23.3.

The method query() of the fixture (line 5 in Listing 23.3) gets the elements of the actual list by calling a method in DiscountGroup. These elements are then mapped into elements of a temporary array of class OrderedDiscountGroup, with the order added, as shown in Listing 23.4.

Figure 23.4 shows some of the objects concerned when Fit runs this table. Inherited by DiscountGroupOrderedList, the doTable() method of RowFixture carries out four major steps:

1.

Determines the class of the elements of the actual list (OrderedDiscountGroup) by calling the method getTargetClass() of the fixture.

Listing 23.4. OrderedDiscountGroup.java
 public class OrderedDiscountGroup {    public int order;    public double maxOwing, minPurchase;    public String futureValue;    public double discountPercent;    public OrderedDiscountGroup(int order, String futureValue,                        double maxOwing, double minPurchase,                      double discountPercent) {       this.futureValue = futureValue;       this.order = order;       this.maxOwing = maxOwing;       this.minPurchase = minPurchase;       this.discountPercent = discountPercent;    } } 

Figure 23.4. Fit Runs the Table


2.

Gathers up the expected list from the table, using the header row to determine the order of the expected fields in each element of the list.

3.

Gathers up the actual list from the system under test by calling the method query() of the fixture.

4.

Compares the actual and expected lists and marks the cells of report rows that match, those that don't quite match, expected rows that are missing, and unexpected rows that are surplus. Surplus rows are those that do not appear in the actual list.

Before it gathers up the expected elements from the table in Figure 23.3, RowFixture uses the five labels in the header row of the table. Each of these labels corresponds to an instance variable in OrderedDiscountGroup, the class returned by getTargetClass() of the fixture.

The first label is order, which corresponds to the public instance variable order in class OrderedDiscountGroup. This instance variable is an int, so RowFixture uses the text in the first cell of each of the expected rows as an int. The other columns correspond to instance variables of type String and double, so some of the element values in these columns need to be converted before the comparisons can be made.

To compare the actual and expected lists, RowFixture attempts to match each expected row against an actual row, based on the table labels. The fixture starts with the leftmost column of the table and works across the cells in the row as a match is made.

Questions & Answers

Q1:

What if a table row is too short or too long?

A1:

An error is given if a row is too short. If it's too long, the extra cells are ignored.

Q2:

Does the future value have to be a String in the system under test?

A2:

No. It could be stored as an int and converted to a String in the fixture to make the tests readable. It's much the same issue as with a user interface: presenting data clearly.

Q3:

What if there are thousands of elements?

A3:

For most testing purposes, we'd try to keep the number of test cases down. Stress testing with large numbers is a different matter.

Q4:

What if the order of the DiscountGroups didn't matter? Would we still have to make a copy of the elements with OrderedDiscountGroup?

A4:

Yes, we would with RowFixture, which requires access to public instance variables. As discussed in Section 28.3 on p. 232, however, a copy would not be needed with SetFixture, which handles property getter methods as well as public instance variables.



    Fit for Developing Software. Framework for Integrated Tests
    Fit for Developing Software: Framework for Integrated Tests
    ISBN: 0321269349
    EAN: 2147483647
    Year: 2005
    Pages: 331

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