The main argument for supporting static analysis, including type checking, is that the results apply to all possible runs of the program, while unit tests only guarantee that the tested components (on the platform on which they are tested) apply only to specific inputs to the test component.
The main argument for supporting unit testing is that it is easier to handle. You can test many of your programs ' constraints, which go far beyond what static analysis tools can achieve over the same period.
Allow me to take the liberty of saying: I think it is a mistake to see these two tools as opposites. Each of these tools helps build a more robust program. In fact, they can complement each other in a very powerful way.
Each of these tools has its own strengths and is particularly useful for supplementing another tool:
Unit tests show how the program works by showing the common paths that are performed.
The Profiling Tools can check the coverage provided by the unit test.
Let's look at each of these attributes and discuss some of the tools that can help you bring their strengths to other methods.
Show unit tests for common execution paths
The unit test suite provides a solid foundation for sample usage of program components. By examining how a test runtime program works, the profiling tools can make tentative guesses about the invariants that developers want to keep in the program (as they do with the programmer reading Unit tests).
There is another way in which unit tests can be an executable form of documentation. After inferring a speculative invariant from a particular to a general in the running of a unit test, the profiling tool can try to verify the existence of invariants from general to special, or it can annotate the code with assertions that can be checked at run time.
In either case, before the tool does any other work, it is a good idea to return a report of the inferred set of invariants to the user asking what invariants they really want. Incidentally, if such tools report many invariants to the user that they do not want, this may be a signal that the unit tests the problem-for example, they are not general enough.
The tool that can be used in this way with unit tests is daikon, a free, experimental tool from the program Analysis team at MIT's Mike Ernst. Daikon the operation of the analyzer (for example, the operation of unit tests) and attempts to speculate on invariants. It then asks the user if they want the invariants and inserts the invariants that the user wants as assertions into the program.
For example, suppose we write a vector (vectors) adapter that implements the interface Sequence, which contains method lookup for retrieving elements and method inserts to place the element at the end of the vector. Method Lookup has an index I, which is used to access the vectors it contains.
Assume that the length of the array is stored in the field length. By maintaining the length of the adapter, we can remove the element from its tail without notifying the vector itself.
Let's write a simple test case for this hypothetical simple adapter:
Listing 1. Test cases for simple lookup methods in vector containers
import junit.framework.TestCase;
public class VectorAdapterTest extends TestCase {
public VectorAdapterTest(String name) {
super(name);
}
public void testLookupAndInsert() {
VectorAdapter v = new VectorAdapter();
v.insert("this");
v.insert("is");
v.insert("a");
v.insert("test");
assertEquals("Retrieved and inserted elements don't match",
"a",
v.lookup(2));
}
}