J2EE开发平台的软件测试技术.docx
《J2EE开发平台的软件测试技术.docx》由会员分享,可在线阅读,更多相关《J2EE开发平台的软件测试技术.docx(11页珍藏版)》请在冰豆网上搜索。
![J2EE开发平台的软件测试技术.docx](https://file1.bdocx.com/fileroot1/2022-11/20/dc5769ae-b28a-45c0-abee-be36ae785980/dc5769ae-b28a-45c0-abee-be36ae7859801.gif)
J2EE开发平台的软件测试技术
J2EE开发平台的软件测试技术
前言─以测试为导向的软件开发流程
软件开发流程的新兴观念是将软件测试的角色,提升为系统开发时每一个阶段都必须要持续且反复进行的重要任务,确保每一个阶段都能及早发现潜藏于系统内的危险因子。
当某一个阶段的测试结果无法达到预期的要求时,就必须回溯到之前的开发阶段,再次分析和审核,这种过程称之为重构(Refactoring)。
配合重构的机制,让系统的品质都能够在严密的测试监控下持续成长。
不过由于网络时代的革命兴起之后,软件系统的架构变得更为复杂,相对的软件测试的发展也更显得重要。
J2EE平台内的软件测试
XP只定义了两种测试的层级,第一种层级是「单元测试」,因为单元测试的用意是为了检验程序代码是否合乎逻辑,而且是针对系统内部的模块来测试,因此又可以称做为程序逻辑测试(CodeLogicTesting)。
为了因应不同的应用程序开发平台的特殊架构,在J2EE的平台里,还发展出与J2EEContainer紧密结合的整合测试(IntegrationTesting)。
另一种层级是接受度测试(AcceptanceTesting),又称作功能测试(FunctionalTesting)。
在软件测试中还有一个大家常听到的是效能测试(PerformanceTesting)。
由于效能测试与客户的需求是密不可分,所以将它归类为接受度测试的延伸应用。
最后归纳起来,一个J2EE平台可能所需要的测试流程,以及测试之间的关系,如图一所示。
在Web层内软件测试的概念与流程,如图二所示,其中键头旁的数字符号代表着整个测试流程的执行步骤。
首先先准备好受测数据与受测系统之后,借着虚拟浏览器来发出request,向受测系统取得包裹着HTML code的response。
然后再利用测试平台来协助我们进行受测数据与预期值的比对工作。
当比对后所回报的结果都是正确无误时,代表着受测系统的功能可以正常运作了。
图中的测试平台与虚拟浏览器在测试中扮演着关键的角色。
虽然发展测试平台的概念已经行之有年了,然而具备有可延伸且开放式架构的测试平台并不多,其中OpenSource社群以Java"target=_blank>Java开发出来的JUnit,是极具代表性的测试平台。
1单元测试平台─JUnit
JUnit平台的设计架构是采用了命令(Command)和复合(Composite)两种设计模式(DesignPattern)做为关键的组成架构。
在JUnit平台中的核心类别是TestCase,而每一个TestCase代表着一个命令对象。
TestCase包含数个testmethod,用来测试被测类别内publicmethod的产出对象与预期的结果是否相同。
在JUnit平台内有提供数种用来协助比对的assertmethod。
JUnit平台里还有另一个核心类别是TestSuite,而每一个TestSuite代表着一个复合的对象。
一个TestSuite可以由数个TestCase或是数个TestSuite组成,因此可以根据测试的需求,拼凑出多个的TestSuite。
整个JUnit测试平台的组成架构,如图三所示。
在了解了JUnit平台的架构之后,我们便可以运用JUnit平台来发展受测系统的整合测试与功能测试。
代码实例:
importjunit.framework.*;
importjava.util.Vector;
publicclassVectorTestextendsTestCase{
protectedVectorfEmpty;
protectedVectorfFull;
publicVectorTest(Stringname){
super(name);
}
publicstaticvoidmain(String[]args){
junit.textui.TestRunner.run(suite());
}
protectedvoidsetUp(){
fEmpty=newVector();
fFull=newVector();
fFull.addElement(newInteger
(1));
fFull.addElement(newInteger
(2));
fFull.addElement(newInteger(3));
}
publicstaticTestsuite(){
returnnewTestSuite(VectorTest.class);
}
publicvoidtestCapacity(){
intsize=fFull.size();
for(inti=0;i<100;i++)
fFull.addElement(newInteger(i));
assertTrue(fFull.size()==100+size);
}
publicvoidtestClone(){
Vectorclone=(Vector)fFull.clone();
assertTrue(clone.size()==fFull.size());
assertTrue(clone.contains(newInteger
(1)));
}
publicvoidtestContains(){
assertTrue(fFull.contains(newInteger
(1)));
assertTrue(!
fEmpty.contains(newInteger
(1)));
}
publicvoidtestElementAt(){
Integeri=(Integer)fFull.elementAt(0);
assertTrue(i.intValue()==1);
try{
Integerj=(Integer)fFull.elementAt(fFull.size());
}catch(ArrayIndexOutOfBoundsExceptione){
return;
}
fail("ShouldraiseanArrayIndexOutOfBoundsException");
}
publicvoidtestRemoveAll(){
fFull.removeAllElements();
fEmpty.removeAllElements();
assertTrue(fFull.isEmpty());
assertTrue(fEmpty.isEmpty());
}
publicvoidtestRemoveElement(){
fFull.removeElement(newInteger(3));
assertTrue(!
fFull.contains(newInteger(3)));
}
}
importjunit.framework.*;
importjunit.runner.BaseTestRunner;
publicclassAllTests{
publicstaticvoidmain(String[]args){
junit.textui.TestRunner.run(suite());
}
publicstaticTestsuite(){
TestSuitesuite=newTestSuite("FrameworkTests");
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(newTestSuite(TestCaseClassLoaderTest.class));
}
returnsuite;
}
staticbooleanisJDK11(){
Stringversion=System.getProperty("java.version");
returnversion.startsWith("1.1");
}
}2整合测试的观念与Cactus应用
整合测试提供了J2EEContainer的环境,可以快速轻易地检验出DomainObject与J2EEContainer的互动行为是否合乎逻辑。
因此整合测试的对象是以一个EJB、Servlet或是JSP的程序代码为基本单元。
OpenSource社群的Jakarta计划中的子计划Cactus,即是为了实作整合测试用的平台而诞生的。
Cactus基本上也是延伸JUnit平台而发展出来的,因此它除了原有基本的method之外,还提供了可以用来模拟浏览器的内部行为的beingxxx()和endxxx()的method。
这两个method来这些method的执行顺序和与WebContainer互动的行为模式,如图四所示。
我们利用beginxxx()来设定要传递给受测对象的字符串参数。
执行完beginxxx()后,会发出request将参数名称与参数值传递到WebContainer。
TestCase会执行setUp(),将受测对象所需要的对象环境建立起来,接着在testxxx()执行存取受测对象的动作。
当存取受测对象的动作执行完后,便可以检验受测对象可能存放在session的产出物。
然后在WebContainer会执行释放资源的动作,然后将response回传到Client端。
最后在Client端执行endxxx()来进行比对HTMLcode是否和预期值相同,执行完endxxx()时也代表一个整合测试的结束。
将这五个method所执行的功能汇整如表一所示。
虽然Cactus架构提供了受测对象产出物与预期结果的比对功能,但是当回传的HTMLcode的内容过于庞大复杂时,反而不利于比对的工作。
因此采用了一个实用性的做法。
此做法是在JSP或servlet欲产出的HTMLcode的程序代码里,于关键的卷标内添加ID这种属性。
当endxxx()要进行比对前,先读取记载着ID属性值与预期值的外部数据文件,再透过DOM的存取机制来取得HTMLcode,便能够快速地比对关键的数据。
不仅可以将比对的工作模块化,更能够在不需要重新编译测试码的情形下,随时变更预期值。
读者们若有遇到相似的问题时,不妨可以采用与相同的策略来解决。