8应用 Rational 工具简化基于 J2EE 的项目.docx
《8应用 Rational 工具简化基于 J2EE 的项目.docx》由会员分享,可在线阅读,更多相关《8应用 Rational 工具简化基于 J2EE 的项目.docx(13页珍藏版)》请在冰豆网上搜索。
8应用Rational工具简化基于J2EE的项目
应用Rational工具简化基于J2EE的项目,第8部分:
测试软件
StevenFranklin(steve@),软件设计师和过程专家
StevenFranklin在软件的设计、架构和工程过程方面有非常广泛的背景,这些经验通常被用到大的,分布式的信息管理和控制系统中。
他从1997年开始使用Rational工具,他主要的兴趣在XML、J2EE、无线和软件工程技术方面。
你可以通过steve@联系Steven.
简介:
当我们正在进行的样例项目进入到了这个阶段时,我们开始大量的使用Rational的测试工具来完成项目的单元测试工作,尤其是在功能测试(包括脚本化的GUI测试)方面。
本文是演示了在分布式的、基于J2EE的项目中使用Rational工具的系列文章(如下面所列)的第8部分。
∙第1部分:
项目介绍;高层次计划
∙第2部分:
风险管理;需求管理
∙第3部分:
模型创建和访问控制;需求分析
∙第4部分:
用例细化;产成报告;工具和技术选择
∙第5部分:
体系架构和设计
∙第6部分:
详细设计;早期开发;双向工程;早期单元测试
∙第7部分:
继续开发;早期的构建;演示
∙第8部分:
单元测试策略;功能测试;GUI测试脚本
∙第9部分:
系统构建和测试;缺陷跟踪;产品交付
∙第10部分:
项目完成;结论;未来的工作
本文中所虚构我们是一家软件公司LookoffTechnologiesIncorporated,我们的客户AudiophileSpeakerDesign,Inc.(ASDI),它雇用我们实现他们最初的IT需求。
对于更详细的信息,参见第1部分。
本文是这个系列文章的第8部分,本文中对最初在这个系列的第6部分介绍的测试方面的主题进行了详细的讨论。
在第6部分的文章中,我们看到了在早期的开发当中我们开始使用RationalPurify和RationalQuantify检查内存的使用情况和性能的瓶颈。
同时也讨论了我们在早期的单元测试工作的很多细节。
本文将描述这些工作的进展,并回顾我们使用Rational测试工具的自动化测试的能力来减少测试的成本,主要是RationalPureCoverage和RationalRobot的使用情况。
在项目的这个阶段,我们主要关注在功能测试(包括GUI测试)上,虽然我们也从事了一些早期的负载测试。
注意,这里使用的Rational统一过程(RUP)术语反映了测试的两个不同的维度:
“单元测试”是在将要被测试的软件的开发阶段进行的—在这个时候测试是针对最小的可测试的软件单元的—而“功能测试”和“负载测试”是针对特定测试目标的,不管是在被测试软件的哪个开发阶段。
本文中所讨论的关于单元测试的大多数内容也可以应用在我们后面的开发阶段的测试工作中(例如,在集成测试期间合并不同的组件或者子系统)。
第8部分快照
在第8部分演示的工具和技术:
∙RationalPureCoverage—用于在单元测试期间分析代码的覆盖率(代码被执行的次数)
∙RationalRobot—为可重复的自动化执行录制和回放测试脚本
∙RationalAdministrator—用于创建项目,与RationalRobot一起使用,关联与项目相关的测试脚本
∙RationalTestManager—组织和管理测试,并查看测试的结果
被创建或者更新的产物:
∙Robot测试脚本—为自动化测试的执行而被创建
单元测试
在开发的进展过程中,我们发现我们的单元测试工作超过了我们的开发工作,因为我们正在构建的应用具有非常复杂的用户交互。
单元测试总是要求大量的工作,并且我们也许没有足够的预算和时间来执行大量的单元测试工作。
我们发现我们的GUI测试,包括单调的手工测试的过程,尤其减慢了我们的速度。
虽然ASDI项目的第1阶段只是一个概念上的验证,但是我们也具有艰苦的时间忍耐在系统中显而易见的bug。
在拥有坚固、可靠的软件和频繁的集成、快速的演示之间找到一个平衡是非常不容易的。
我们定义了第1阶段项目的范围,这样我们就必须进行不止一次的技术上的演示;客户期望演示是一个可以使用的系统的beta版本。
这里,我们将看一下我们的单元测试工作的范围,我们可以选择(或者不)使用自动化的能力,并且我们使用RationalPureCoverage来确定我们测试的彻底性。
测试的范围
单元测试的范围—什么、多少次和什么时候测试—是几个可变量的基础,包括:
∙软件的复杂程度
∙产品的特性和接口
∙被测试部分对整个产品是否是非常关键的
∙团队对软件中缺陷的容忍程度
在代码测试的次数方面,在之前的项目中我们没有打算在我们的软件中进行100%代码覆盖率的测试。
完全的覆盖是非常昂贵的并且很难达到,因为我们必须要手工的检查我们的代码以确定哪一行代码没有被测试覆盖到。
对单元测试的小的变化将要求我们重新检查代码以确保完全的覆盖率被维护。
然而,我们得感谢RationalPureCoverage,在ASDI项目中我们能够容易得实现了接近100%的代码覆盖率(由于项目预算和范围的原因,少量的未测试的残留是被允许的)。
PureCoverage很大程度的简化了检查代码覆盖率的任务,这使识别哪一部分的代码已经或者还没有被测试变得非常简单。
就像我们在这个系列的第6部分提到的那样,我们的单元测试工作几乎与核心的软件开发本身开始的一样早。
我们多数的开发人员在他们拥有一个能够被测试的软件单元不久就开始编写单元测试。
他们喜欢当代码在他们的头脑中产生时测试软件的内部构件。
单元测试的执行总是先于系统的构建;将明显能够通过单元测试来消除的简单缺陷引入到一个构建版本中是让人不可接受的。
单元测试总是在代码被分发检查之前被执行。
此外,开发人员以规范的基础运行他们的单元测试以确保他们的定期变化不会破坏软件。
我们的方法不像一些软件方法那样激进—比如极限编程(XP),在XP中单元测试的开发通常是先于代码的开发的—但是我们将单元测试当作是一个重要的软件开发的早期步骤。
自动化的能力
这里当然也有一些如何进行测试的问题,特别是什么样的测试应该被自动化的范围。
编写“后台”(非GUI)代码的开发人员是幸运的,他们能够编写自动化的测试,包括Java驱动程序、代码存根和脚本。
然而,就像我们早些时候提到的,GUI开发人员的测试是更加困难的。
对于我们的非GUI测试,我们观察了与每一个类相关联的单元测试的习惯;我们编写驱动代码访问类,并报告成功或者是失败。
我们尝试使用能够为我们自动生成、管理和运行测试的测试框架,比如被XP所推荐的那些工具,但是他们将产生混杂的结果。
虽然理论是很好的,但是这些框架(包括,比如JUnit)对于我们的项目目的来说来是不够成熟的。
不过,我们的开发人员非常自信如果他们有时间熟悉和对这些工具进行改进,这些测试框架对我们的单元测试是非常有价值的。
我们也许在将来的项目中更多的使用这些测试框架。
在我们的ASDI项目中,采用XP的方法也许是太冒险了;相反,我们更加愿意接受XP在控制和风险降低方法方面的概念和思想。
你能够在theXP网站上找到大量有关XP思想的内容。
我们没有使用Rational的测试工具来测试非GUI的代码,因为我们觉得他们不能达到一个足够底层的级别。
对于自动化测试我们的GUI驱动的代码,Rational的测试工具真的表现的非常出色。
用户界面测试是非常手工和交互的,并且要求大量的内容确认;Rational的测试工具以一种一致的并快速的方式使我们反复的进行这些测试变得更加的简单容易。
代码覆盖率
通过使用RationalPureCoverage,在我们的单元测试执行期间,我们能够大幅的降低我们花在确定代码覆盖率上的时间—也就是说,哪些方法或者代码行被执行或者被遗漏。
这个工具能够使我们观测我们提供的代码覆盖测试,然后决定是改进测试还是通过手工检查的方法来测试代码。
PureCoverage除了可以支持C或者C++的应用程序以外,还可以支持Java程序,并且可以通过与Quantify相同的方式来配置和运行(在这个系列的第6部分被讨论过)。
这个工具能够使我们浏览我们的单元测试;以两种方法进行代码覆盖测试:
使用CoverageBrowser或者指定文件的CoverageFileview方式。
使用CoverageBrowser的方式(图1),我们能够看到在单元测试中被包括的每一个文件(和目录)的代码覆盖测试的统计学的总结。
这些统计表包括了所有方法的调用次数,方法被访问或者遗漏的次数,还包括被访问或者遗漏的代码行的数量。
图1:
CoverageBrowser
我们能够双击一个在总结中的方法来进入CoverageFileview,仅仅显示在那个方法中哪些代码行被访问或者被遗漏。
就像被显示在图2中的例子,被遗漏的代码行被用红色突出出来(被访问的代码行用蓝色标识)。
图2:
CoverageFileview
功能测试
功能测试根据被定义在用例中的需求来验证软件是否正确的工作。
为了确保我们测试了所有的需求,我们在设计和组织我们的功能测试时使用RationalRobot和RationalTestManager。
(一个关于使用Robot的功能测试策略的讨论能够在Robot的用户指南中被找到。
)Robot能够使测试脚本更加容易的被录制,然后为自动化测试回放。
使用Robot能够创建两种类型的测试脚本:
∙GUI脚本记录你的用户界面动作,当进行回放时,就像一个用户在操作应用的登陆和控制程序的窗口。
一些客户端的测试—比如,嵌入到我们的Web应用中的ActiveX控件—需要使用这些脚本。
因为GUI测试为我们造成了特殊的问题,因此这类的功能测试将在下一部分被详细的讨论。
∙VUscripts当你使用它在包的级别上跟踪什么样的网络信息被发送和接受时,检测你的应用。
当进行回放时,这些脚本不必登陆应用就可以重新运行测试,这使他们比GUI脚本执行的更快。
我们为我们的commandgateway的非GUI功能测试和B2B的负载测试使用VU脚本。
我们尽可能早的开始创建我们的功能测试集合,因为这些测试对工程团队来说是非常有价值的工具。
我们在代码被分发检查之前适当的拥有测试脚本的目标有时是很难实现的,可能是因为代码的一些部分和一些组件要比其他的代码和组件花费更多的时间来完成,或者是因为集成和测试(I&T)团队太慢以至不能及时的完成测试脚本。
在一种情况下,当用户界面仍然在变化时,测试脚本已经被完成了;虽然一些返工是必要的,但是变化的出现是相当容易集成的。
一旦我们拥有了一个强有力的功能测试集合,重新测试系统将是非常容易的。
这样当你需要在后来的迭代中重新测试系统小的改变时得到很大的回报,并且可以确保变化不会影响其他的代码部分。
我们映射我们的功能测试脚本到用例上,以便我们可以立即知道当被关联到被给定的用例的需求被修改时哪一个测试应该被运行。
GUI测试
当非GUI代码的开发人员非常高效的进行他们的单元测试工作时,JSP/servlet的开发人员将很难的保证时间的进度。
刺痛他们的是测试GUI域的过程,这个过程包括反复的执行下面的步骤:
1.在数据库中建立测试数据。
2.通过Web浏览器登陆应用。
3.导航被测试的页面(一个表单要被填充)。
4.在页面上填写一个或者多个域,依赖具体的测试。
5.点击适当的按钮提交表单。
6.检查结果。
7.使用不同的测试(不同的域值或者不同的域)返回到步骤4,直到所有合理的组合都被测试。
一些GUI测试尤其令人讨厌,包括相同的入口,在几个域中填写冗长的值。
可以使用剪切和粘贴,但是对于团队来说一遍一遍的重复这些测试仍然是非常琐碎的工作。
有些页面有50个不同的测试必须被执行,每个测试都包括很多的步骤。
虽然我们最初不倾向使用Rational的测试工具,但是我们觉得我们在GUI上的困难是我们深入研究Rational测试工具的很好的理由。
我们决定使用RationalRobot来自动化我们GUI的大部分测试。
我们通过以下的方式调整了这些测试:
∙开发人员为每一个测试起草一个单元测试说明。
∙初级的集成与测试团队成员接受单元测试说明并基于当前的软件构建版本创建测试脚本。
∙单元测试脚本是可配置管理的,以便对测试脚本的变更可以被跟踪。
∙定期的,一个开发人员给集成与测试团队执行单元测试脚本的任务,并提供一个根据单元测试说明指明成功或者失败的报告。
这个方法工作的非常好。
它不仅仅在集成与测试团队没有太多的事情做的开发过程的早期阶段给他们在更多的工作,而且也给他们一个机会通过揭示单元测试说明来了解整个软件系统。
此外,我们为GUI测试使用Robot的经验也为阿我们对其他的功能测试脚本进行了准备。
当RationalRobot启动时,它需要一个已存在项目(使用RationalAdministrator创建的)的选择,测试脚本将与这个项目进行关联。
在我们的例子中,项目的定位必须是在网络上可访问的,以便我们能够在整个团队中共享项目的数据库。
我们在Administrator中创建了ASDI项目,如图3所示,并且当Robot提示我们选择一个项目时,我们选择了这个项目。
图3:
使用RationalAdministrator创建一个项目
一个验证测试的例子
作为一个GUI测试的非常简单的例子,我们需要确证对于我们的partSearch.jsp页面来说客户端的验证是行为正确的,这个页面执行了JavaScript的代码来验证他们域。
每个ASDI的条件,部分数字被输入到整个页面中,比如,必须是比0要大的整型数字;如果一个用户输入一个无效的数字,JavaScript代码就会报告一个错误,并且不会送坏的数据到服务器。
我们在FormChek.js文件中编写了我们自己的验证代码。
适当的使用这个代码,一个负数的输入会弹出如图4所示的窗口。
图4:
适当的partSearch.jsp页面验证
创建测试脚本
我们在Robot中创建了一个测试脚本来测试数字域的验证是否示适当的。
首先Robot提示我们为脚本提供一个名字(图5)。
图5:
录制一个新的GUI脚本
在点击OK这后,我们被提供了一个录制控制器(图6),然后当Robot录制我们的动作时,我们使用我们的基于窗口的应用。
在这个例子中,我们启动了InternetExplorer5,在partSearch.jsp页面进行浏览,输入一个坏的数字(-123456),点击页面上的Submit按钮。
图6:
Robot录制控制器
Robot将我们的动作记录在一个GUI脚本中(图7)。
这是一个非常简单的例子;我们实际的测试会包括更加复杂的测试脚本。
我们不用创建成百上千个独立的脚本,而是尽量为每一个屏幕界面设计一个大的脚本。
在Robot的文章中有进行测试设计的非常详细的信息,我们能够从Robot文档中所推荐的内容中得到大量的借鉴。
图7:
简单的RobotGUI脚本
通过使用易读的并且可以容易的进行编辑的脚本,我们就不必为只是有很小差异的测试重复的录制测试脚本了。
有时我们可以不用重新运行测试就直接编辑测试脚本,或者我们只是重新录制一个测试的一小部分,然后将它粘贴到已存在的脚本中。
运行测试
为了再一次运行测试,我们简单的在Robot的录制控制器上(或者选择File菜单上的Playback)点击“play”按钮。
脚本就像我们最初执行测试一样回放我们的测试操作,并且当脚本运行完成时,RationalTestManager被启动来总结我们的测试结果。
对于上面那个简单的例子,TestManager在图8中显示的结果表明,测试脚本运行的结果是测试被通过。
图8:
TestManager报告Robot的测试通过
假设我们想测试代码的错误处理能力,比如坏的数字不再被捕获—也就是说,没有出现一个指明错误的窗口,我们的应用就会将整个数据传送到servlet来执行查询。
当我们通过回放脚本重新运行这个GUI测试时,Robot将会捕获这个问题,并且将结果写到报告中(图9),包括显示出这个测试是失败的。
图9:
TestManager报告Robot测试的失败
总结
当我们开始ASDI项目时,我们期望使用Rational的分析和设计工具而不是Rational的测试工具。
到项目第一阶段的这个时期,我们非常惊讶并且也很高兴的看到我们通过使用Rational的测试工具自动化并且改进了我们的测试过程。
这些工具都有一个坚实的学习曲线,但是一旦我们掌握我们每个工具的使用方法,我们的集成与测试团队的生产力将大大的提高。
在一些情况下,个体开发人员使用象RationalPurify、Quantify和PureCoverage这样的工具为他们的单元测试工作提供补充。
其他的工具,比如RationalRobot,则需要集成与测试团队具有更高的技能并投入更大的注意力。
计划未来
团队仍然必须在系统级别上承担集成和测试的任务。
多数的单元测试工作被分包给了开发人员,但是我们还需要更加全面和正式的测试子系统和整个系统。
这就意味着我们需要正式的构建版本、最终的构建文档和在集成与测试上的重要关注。
特定目的的负载测试只是我们测试工作中的一小部分,但是它在整个系统的测试中却是非常重要的。
幸运的是,我们的测试集合已经完成了95%,并且我们还稍稍的比计划的时间提前了一点,因此我们能够有一些额外的精力来关注系统的测试以确保高质量的第一阶段的系统交付。
主要风险
我们的风险列表在此刻已经非常的短了。
客户在演进系统上的合作并不太令人惊讶,我们的技术风险已经非常少了,非常感谢工程团队带来的良好的进展。
现在我们必须对我们的代码开发进行最后的加工、执行系统的测试、识别系统中的任何缺陷并按计划交付阶段一的系统给客户。
当团队接近主要阶段的尾声时,及时的将所有的细节包装起来通常时很难的。
如果我们想避免超出计划,我们就需要系统有少量的缺陷,并且能够快速的矫正在测试中发现的任何问题。