1、J2EE开发平台的软件测试技术J2EE开发平台的软件测试技术前言以测试为导向的软件开发流程 软件开发流程的新兴观念是将软件测试的角色,提升为系统开发时每一个阶段都必须要持续且反复进行的重要任务,确保每一个阶段都能及早发现潜藏于系统内的危险因子。当某一个阶段的测试结果无法达到预期的要求时,就必须回溯到之前的开发阶段,再次分析和审核,这种过程称之为重构(Refactoring)。配合重构的机制,让系统的品质都能够在严密的测试监控下持续成长。不过由于网络时代的革命兴起之后,软件系统的架构变得更为复杂,相对的软件测试的发展也更显得重要。J2EE平台内的软件测试 XP只定义了两种测试的层级,第一种层级是
2、单元测试,因为单元测试的用意是为了检验程序代码是否合乎逻辑,而且是针对系统内部的模块来测试,因此又可以称做为程序逻辑测试(Code Logic Testing)。为了因应不同的应用程序开发平台的特殊架构,在J2EE的平台里,还发展出与J2EE Container 紧密结合的整合测试(Integration Testing)。 另一种层级是接受度测试(Acceptance Testing),又称作功能测试(Functional Testing)。在软件测试中还有一个大家常听到的是效能测试(Performance Testing)。由于效能测试与客户的需求是密不可分,所以将它归类为接受度测试的延伸
3、应用。最后归纳起来,一个J2EE平台可能所需要的测试流程,以及测试之间的关系,如图一所示。在Web层内软件测试的概念与流程,如图二所示,其中键头旁的数字符号代表着整个测试流程的执行步骤。首先先准备好受测数据与受测系统之后,借着虚拟浏览器来发出request,向受测系统取得包裹着HTMLcode的response。然后再利用测试平台来协助我们进行受测数据与预期值的比对工作。当比对后所回报的结果都是正确无误时,代表着受测系统的功能可以正常运作了。图中的测试平台与虚拟浏览器在测试中扮演着关键的角色。虽然发展测试平台的概念已经行之有年了,然而具备有可延伸且开放式架构的测试平台并不多,其中OpenSou
4、rce社群以Java target=_blankJava开发出来的JUnit,是极具代表性的测试平台。1 单元测试平台 JUnit JUnit平台的设计架构是采用了命令(Command)和复合(Composite)两种设计模式(Design Pattern)做为关键的组成架构。在JUnit平台中的核心类别是TestCase,而每一个TestCase代表着一个命令对象。TestCase包含数个test method,用来测试被测类别内public method的产出对象与预期的结果是否相同。在JUnit平台内有提供数种用来协助比对的assert method。 JUnit平台里还有另一个核心类别
5、是TestSuite,而每一个TestSuite代表着一个复合的对象。一个TestSuite可以由数个TestCase或是数个TestSuite组成,因此可以根据测试的需求,拼凑出多个的TestSuite。整个JUnit测试平台的组成架构,如图三所示。在了解了JUnit平台的架构之后,我们便可以运用JUnit平台来发展受测系统的整合测试与功能测试。代码实例:import junit.framework.*;import java.util.Vector;public class VectorTest extends TestCase protected Vector fEmpty;protec
6、ted 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);publi
7、c 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
8、();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.siz
9、e(); 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 In
10、teger(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.addTestSuit
11、e(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.c
12、lass);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 boo
13、lean 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基本上也是延伸JU
14、nit平台而发展出来的,因此它除了原有基本的method之外,还提供了可以用来模拟浏览器的内部行为的beingxxx( )和endxxx( )的method。这两个method来 这些method的执行顺序和与Web Container互动的行为模式,如图四所示。我们利用beginxxx( )来设定要传递给受测对象的字符串参数。执行完beginxxx( )后,会发出request将参数名称与参数值传递到Web Container。TestCase会执行setUp( ),将受测对象所需要的对象环境建立起来,接着在testxxx( )执行存取受测对象的动作。当存取受测对象的动作执行完后,便可以检验
15、受测对象可能存放在session的产出物。然后在Web Container会执行释放资源的动作,然后将response回传到Client端。最后在Client端执行endxxx( )来进行比对HTML code是否和预期值相同,执行完endxxx()时也代表一个整合测试的结束。将这五个method所执行的功能汇整如表一所示。虽然Cactus架构提供了受测对象产出物与预期结果的比对功能,但是当回传的HTML code的内容过于庞大复杂时,反而不利于比对的工作。因此采用了一个实用性的做法。此做法是在JSP或servlet欲产出的HTML code的程序代码里,于关键的卷标内添加ID这种属性。当endxxx( )要进行比对前,先读取记载着ID属性值与预期值的外部数据文件,再透过DOM的存取机制来取得HTML code,便能够快速地比对关键的数据。不仅可以将比对的工作模块化,更能够在不需要重新编译测试码的情形下,随时变更预期值。读者们若有遇到相似的问题时,不妨可以采用与相同的策略来解决。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1