With this model, test cases are written one at a time, without regard to a specific overall ordering of test cases. Then once a particular test case is tested in an expected-negative test run, the methods referred to in the test case are implemented, and the test case is once again executed (this time in an expected-positive test run). Once this test run is successful, the next test case is written, and an expected-negative test run is conducted with that test case. If any of the methods in this test case are not written yet, they are written now, and an expected-positive test run is conducted. In subsequent iterations after the first, it may not be necessary to implement all the methods referred to in that iteration's test case, because some of those methods may have been implemented in a previous iteration. Assume that n test cases and k methods are in the class under development. We note that the entire set of n test cases may not be known a priori but may very well be developed individually as each is tested. Still, we assume that the total number is finite (n). We can state this model as a relatively straightforward procedure. For each test case 1 … n:
We now apply this testing model in the context of our OrderedList class, for which we identified 13 test cases in Table 13.1. As earlier, we do not assume that all these test cases are known a priori. Because our process does not dictate a specific ordering of test case runs in the absence of specific business values, we arbitrarily assume the same ordering as in Table 13.1. We then have the following:
Given the order of test cases presented in Table 13.1, we can determine the number of methods that must be implemented on a particular iteration before an expected-positive run for each test case. The number varies depending on how many methods have been implemented on a previous iteration. For example, if test case 1 is tested first, three methods are referred to by the test case, and all three must be implemented before an expected-positive run of that test case. However, if test case 2 is tested next (as earlier), two methods are referred to by the test case, but only one must be implemented in this iteration (because the constructor was already developed in the previous iteration). Table 13.2 lists the methods referenced by each test case and the methods that must be developed as each test case is run, assuming this particular ordering of test runs. Ideally, it would be nice to minimize the number of methods that are developed at each iteration. The smaller the number of methods that are introduced anew as each test case is run, the easier it will be to pinpoint errors. In this particular example, only two test cases could be completed after the first four methods were developed. Two additional methods had to be written before test case 3 could be completed, at which point test cases 4 through 9 could also be completed. Of course, the number of methods that must be developed at each iteration depends heavily on the order in which the test cases are run. However, other than business value, nothing in this particular process model dictates this order. A second issue is that test cases should ideally be run as early in the development process as possible. In this example, test cases 8 and 9 could be run immediately after test case 2, immediately after member was written. If we ran these test cases earlier, defects in the methods they refer to (such as add, which is heavily referred to by almost all the remaining test cases) could be exposed in the context of a smaller number of methods. Again, this simpler context could make it easier to pinpoint errors.
In the next section, we consider an alternative testing model that specifies the ordering of test case runs and (correspondingly) method development. |