虽然发展测试平台的概念已经行之有年了,然而具备有可延伸且开放式架构的测试平台并不多,其中OpenSource社群以Java开发出来的JUnit,是极具代表性的测试平台。
1 单元测试平台─ JUnit
JUnit平台的设计架构是采用了命令(Command)和复合(Composite)两种设计模式(Design Pattern)做为关键的组成架构。在JUnit平台中的核心类别是TestCase,而每一个TestCase代表着一个命令对象。TestCase包含数个test method,用来测试被测类别内public method的产出对象与预期的结果是否相同。在JUnit平台内有提供数种用来协助比对的assert method。
JUnit平台里还有另一个核心类别是TestSuite,而每一个TestSuite代表着一个复合的对象。一个TestSuite可以由数个TestCase或是数个TestSuite组成,因此可以根据测试的需求,拼凑出多个的TestSuite。整个JUnit测试平台的组成架构,如图三所示。在了解了JUnit平台的架构之后,我们便可以运用JUnit平台来发展受测系统的整合测试与功能测试。

代码实例:
import junit.framework.*;
import java.util.Vector;
public class VectorTest extends TestCase {
protected Vector fEmpty;
protected Vector fFull;
public VectorTest(String name) {
super(name);
}
public static void main (String[] args) {
junit.textui.TestRunner.run (suite());
}
protected void setUp() {
fEmpty= new Vector();
fFull= new Vector();
fFull.addElement(new Integer(1));
fFull.addElement(new Integer(2));
fFull.addElement(new Integer(3));
}
public static Test suite() {
return new TestSuite(VectorTest.class);
}
public void testCapacity() {
int size= fFull.size();
for (int i= 0; i < 100; i++)
fFull.addElement(new Integer(i));
assertTrue(fFull.size() == 100+size);
}
public void testClone() {
Vector clone= (Vector)fFull.clone();
assertTrue(clone.size() == fFull.size());
assertTrue(clone.contains(new Integer(1)));
}
public void testContains() {
assertTrue(fFull.contains(new Integer(1)));
assertTrue(!fEmpty.contains(new Integer(1)));
}
public void testElementAt() {
Integer i= (Integer)fFull.elementAt(0);
assertTrue(i.intValue() == 1);
try {
Integer j= (Integer)fFull.elementAt(fFull.size());
} catch (ArrayIndexOutOfBoundsException e) {
return;
}
fail("Should raise an ArrayIndexOutOfBoundsException");
}
public void testRemoveAll() {
fFull.removeAllElements();
fEmpty.removeAllElements();
assertTrue(fFull.isEmpty());
assertTrue(fEmpty.isEmpty());
}
public void testRemoveElement() {
fFull.removeElement(new Integer(3));
assertTrue(!fFull.contains(new Integer(3)) );
}
}
import junit.framework.*;
import junit.runner.BaseTestRunner;
public class AllTests {
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
public static Test suite() {
TestSuite suite= new TestSuite("Framework Tests");
suite.addTestSuite(ExtensionTest.class);
suite.addTestSuite(TestCaseTest.class);
suite.addTest(SuiteTest.suite()); suite.addTestSuite(ExceptionTestCaseTest.class);
suite.addTestSuite(TestListenerTest.class);
suite.addTestSuite(ActiveTestTest.class);
suite.addTestSuite(AssertTest.class);
suite.addTestSuite(StackFilterTest.class);
suite.addTestSuite(SorterTest.class);
suite.addTestSuite(RepeatedTestTest.class);
suite.addTestSuite(TestImplementorTest.class);
if (!BaseTestRunner.inVAJava()) {
suite.addTestSuite(TextRunnerTest.class);
if (!isJDK11())
suite.addTest(new TestSuite(TestCaseClassLoaderTest.class));
}
return suite;
}
static boolean isJDK11() {
String version= System.getProperty("java.version");
return version.startsWith("1.1");
}
}
2 整合测试的观念与Cactus应用
整合测试提供了J2EE Container的环境,可以快速轻易地检验出Domain Object与J2EE Container的互动行为是否合乎逻辑。因此整合测试的对象是以一个EJB、Servlet或是JSP的程序代码为基本单元。Open Source社群的Jakarta计划中的子计划Cactus,即是为了实作整合测试用的平台而诞生的。
Cactus基本上也是延伸JUnit平台而发展出来的,因此它除了原有基本的method之外,还提供了可以用来模拟浏览器的内部行为的beingxxx( )和endxxx( )的method。这两个method来 这些method的执行顺序和与Web Container互动的行为模式,如图四所示。

我们利用beginxxx( )来设定要传递给受测对象的字符串参数。执行完beginxxx( )后,会发出request将参数名称与参数值传递到Web Container。TestCase会执行setUp( ),将受测对象所需要的对象环境建立起来,接着在testxxx( )执行存取受测对象的动作。当存取受测对象的动作执行完后,便可以检验受测对象可能存放在session的产出物。然后在Web Container会执行释放资源的动作,然后将response回传到Client端。最后在Client端执行endxxx( )来进行比对HTML code是否和预期值相同,执行完endxxx()时也代表一个整合测试的结束。将这五个method所执行的功能汇整如表一所示。
