In Getting Started with GrandTestAuto we saw how our test classes must relate to our production code in order to be run by GrandTestAuto (GTA), as well as how to invoke the tool. We saw that GTA requires tests for all public classes and for all public and protected methods in those classes. This tutorial answers the following questions:
To see some real-life use of GTA, have a look at the unit tests for GTA itself (these, and the rest of the source code, are in the download).
By the design motivation for GTA, protected methods and constructors will need to be invoked from outside the package in which they are defined. There is a little trick to doing this. Suppose that X is a public class in a package p that we are developing:
package p;
public class X {
protected X( String str ) {
//Constructor body ...
}
protected String a() {
//Method body ...
}
}
The trick is to have an extension of X along with our class XTest:
package p.test;
public class XTest {
public boolean constructorTest() {
X x = new XExt( "a string" );
//Test state of x ...
}
public boolean aTest() {
XExt x = new XExt( "a string" );
String str = x.a();
//Test str ...
}
}
class XExt extends X {
protected XExt( String str ) {
super( str );
}
protected String a() {
return super.a();
}
}
This trick will work so long as the class or method under test is not final. Classes that are final and have a protected constructor are exempt from being tested, and so are methods that are protected and final.
As we saw in the first tutorial, test methods take no parameters. How then is it possible to have separate tests for methods that have the same name. Suppose that a class has testable methods as follows:
public boolean meth() ...
public void meth( String str ) ...
protected String meth( char[] c )...
GTA uses a naming pattern to differentiate the tests for these methods. The pattern works by incorporating the parameter types for a method into the test name. So the names of the test methods for the methods above would be:
public boolean methTest() ...
public boolean meth_String_Test() ...
public boolean meth_charArray_Test() ...
The naming pattern for test methods is:
(By unqualified class name is meant the name of the class stripped of its package name.)
As an example of this naming pattern, suppose that class X includes the testable methods m(), m( String ), m( int
) and m( String[], int[][] ). Then
the names of the corresponding test methods would be m_Test(), m_String_Test(),
m_int_Test(), and m_StringArray_intArray2_Test().
In this section we look in detail at the way that GTA ensures that all accessible methods in a package are tested. As usual, we'll work with an example. Consider a package with public classes:
I which is an interface
A which is an abstract class with methods:
public boolean a(); public void b( String ); protected abstract void c(); private void d();
B which extends A, is
not abstract, and has methods:
public void b( String[] ); protected void c(); private void d();
C which extends A, is
not abstract, and has methods:
public void e( int ) throws IOException; protected void c(); String f();
The test sub-package must contain test classes for B and C. The test for B must contain tests for its implementation of b and c. The test for C must contain tests for e and its implementation of c. The method a defined in A must be tested in either BTest or CTest. The method b defined in A is inherited only by C so must be tested in CTest.