23.11.2014 Views

Data Structures and Algorithms in Java[1].pdf - Fulvio Frisone

Data Structures and Algorithms in Java[1].pdf - Fulvio Frisone

Data Structures and Algorithms in Java[1].pdf - Fulvio Frisone

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

A careful test<strong>in</strong>g plan is an essential part of writ<strong>in</strong>g a program. While verify<strong>in</strong>g<br />

the correctness of a program over all possible <strong>in</strong>puts is usually <strong>in</strong>feasible, we<br />

should aim at execut<strong>in</strong>g the program on a representative subset of <strong>in</strong>puts. At the<br />

very m<strong>in</strong>imum, we should make sure that every method <strong>in</strong> the program is tested at<br />

least once (method coverage). Even better, each code statement <strong>in</strong> the program<br />

should be executed at least once (statement coverage).<br />

Programs often tend to fail on special cases of the <strong>in</strong>put. Such cases need to be<br />

carefully identified <strong>and</strong> tested. For example, when test<strong>in</strong>g a method that sorts (that<br />

is, puts <strong>in</strong> order) an array of <strong>in</strong>tegers, we should consider the follow<strong>in</strong>g <strong>in</strong>puts:<br />

• The array has zero length (no elements)<br />

• The array has one element<br />

• All the elements of the array are the same<br />

• The array is already sorted<br />

• The array is reverse sorted.<br />

In addition to special <strong>in</strong>puts to the program, we should also consider special<br />

conditions for the structures used by the program. For example, if we use an array<br />

to store data, we should make sure that boundary cases, such as<br />

<strong>in</strong>sert<strong>in</strong>g/remov<strong>in</strong>g at the beg<strong>in</strong>n<strong>in</strong>g or end of the subarray hold<strong>in</strong>g data, are<br />

properly h<strong>and</strong>led.<br />

While it is essential to use h<strong>and</strong>-crafted test suites, it is also advantageous to run<br />

the program on a large collection of r<strong>and</strong>omly generated <strong>in</strong>puts. The R<strong>and</strong>om<br />

class <strong>in</strong> the java.util package provides several methods to generate r<strong>and</strong>om<br />

numbers.<br />

There is a hierarchy among the classes <strong>and</strong> methods of a program <strong>in</strong>duced by the<br />

caller-callee relationship. Namely, a method A is above a method B <strong>in</strong> the<br />

hierarchy if A calls B. There are two ma<strong>in</strong> test<strong>in</strong>g strategies, top-down <strong>and</strong><br />

bottom-up, which differ <strong>in</strong> the order <strong>in</strong> which methods are tested.<br />

Bottom-up test<strong>in</strong>g proceeds from lower-level methods to higher-level methods.<br />

Namely, bottom-level methods, which do not <strong>in</strong>voke other methods, are tested<br />

first, followed by methods that call only bottom-level methods, <strong>and</strong> so on. This<br />

strategy ensures that errors found <strong>in</strong> a method are not likely to be caused by<br />

lower-level methods nested with<strong>in</strong> it.<br />

Top-down test<strong>in</strong>g proceeds from the top to the bottom of the method hierarchy. It<br />

is typically used <strong>in</strong> conjunction with stubb<strong>in</strong>g, a boot-strapp<strong>in</strong>g technique that<br />

replaces a lower-level method with a stub, a replacement for the method that<br />

simulates the output of the orig<strong>in</strong>al method. For example, if method A calls<br />

83

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!