`
liyiye
  • 浏览: 415055 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

应用 Rational 工具简化基于 J2EE 的项目第 8 部分 :测试软件

阅读更多

本文是演示了在分布式的、基于 J2EE 的项目中使用 Rational 工具的系列文章(如下面所列)的第 8 部分。

  • 第 1 部分: 项目介绍;高层次计划
  • 第 2 部分: 风险管理;需求管理 <!---->
  • 第 3 部分: 模型创建和访问控制;需求分析
  • 第 4 部分: 用例细化;产成报告;工具和技术选择
  • 第 5 部分: 体系架构和设计
  • 第 6 部分: 详细设计;早期开发;双向工程;早期单元测试
  • 第 7 部分: 继续开发;早期的构建;演示
  • 第 8 部分: 单元测试策略;功能测试;GUI 测试脚本 <!---->
  • 第 9 部分: 系统构建和测试;缺陷跟踪;产品交付 <!---->
  • 第 10 部分: 项目完成;结论;未来的工作

本文中所虚构我们是一家软件公司 Lookoff Technologies Incorporated,我们的客户 Audiophile Speaker Design, Inc. (ASDI),它雇用我们实现他们最初的 IT 需求。对于更详细的信息,参见 第 1 部分

本文是这个系列文章的第 8 部分,本文中对最初在这个系列的第 6 部分介绍的测试方面的主题进行了详细的讨论。在第 6 部分的文章中,我们看到了在早期的开发当中我们开始使用 Rational Purify 和 Rational Quantify 检查内存的使用情况和性能的瓶颈。同时也讨论了我们在早期的单元测试工作的很多细节。本文将描述这些工作的进展,并回顾我们使用 Rational 测试工具的自动化测试的能力来减少测试的成本,主要是 Rational PureCoverage 和 Rational Robot 的使用情况。在项目的这个阶段,我们主要关注在功能测试(包括 GUI 测试)上,虽然我们也从事了一些早期的负载测试。

注意,这里使用的 Rational 统一过程(RUP)术语反映了测试的两个不同的维度:“单元测试”是在将要被测试的软件的开发阶段进行的 €€ 在这个时候测试是针对最小的可测试的软件单元的 €€ 而“功能测试”和“负载测试”是针对特定测试目标的,不管是在被测试软件的哪个开发阶段。本文中所讨论的关于单元测试的大多数内容也可以应用在我们后面的开发阶段的测试工作中(例如,在集成测试期间合并不同的组件或者子系统)。

第 8 部分快照

在第 8 部分演示的工具和技术:

  • Rational PureCoverage €€ 用于在单元测试期间分析代码的覆盖率(代码被执行的次数)
  • Rational Robot €€ 为可重复的自动化执行录制和回放测试脚本
  • Rational Administrator €€ 用于创建项目,与 Rational Robot 一起使用,关联与项目相关的测试脚本
  • Rational TestManager €€ 组织和管理测试,并查看测试的结果

被创建或者更新的产物:

  • Robot 测试脚本 €€ 为自动化测试的执行而被创建

51Testing软件测试网Ndirg)H?

单元测试 51Testing软件测试网 A@3Q"oaT6d2p#T@
在开发的进展过程中,我们发现我们的单元测试工作超过了我们的开发工作,因为我们正在构建的应用具有非常复杂的用户交互。单元测试总是要求大量的工作,并且我们也许没有足够的预算和时间来执行大量的单元测试工作。我们发现我们的 GUI 测试,包括单调的手工测试的过程,尤其减慢了我们的速度。

虽然 ASDI 项目的第 1 阶段只是一个概念上的验证,但是我们也具有艰苦的时间忍耐在系统中显而易见的 bug 。在拥有坚固、可靠的软件和频繁的集成、快速的演示之间找到一个平衡是非常不容易的。我们定义了第 1 阶段项目的范围,这样我们就必须进行不止一次的技术上的演示;客户期望演示是一个可以使用的系统的 beta 版本。

这里,我们将看一下我们的单元测试工作的范围,我们可以选择(或者不)使用自动化的能力,并且我们使用 Rational PureCoverage 来确定我们测试的彻底性。

测试的范围 51Testing软件测试网}1t5S.QpG[
单元测试的范围 €€ 什么、多少次和什么时候测试 €€ 是几个可变量的基础,包括:

  • 软件的复杂程度
  • 产品的特性和接口
  • 被测试部分对整个产品是否是非常关键的
  • 团队对软件中缺陷的容忍程度

在代码测试的次数方面,在之前的项目中我们没有打算在我们的软件中进行 100% 代码覆盖率的测试。完全的覆盖是非常昂贵的并且很难达到,因为我们必须要手工的检查我们的代码以确定哪一行代码没有被测试覆盖到。对单元测试的小的变化将要求我们重新检查代码以确保完全的覆盖率被维护。然而,我们得感谢 Rational PureCoverage ,在 ASDI 项目中我们能够容易得实现了接近 100% 的代码覆盖率(由于项目预算和范围的原因,少量的未测试的残留是被允许的)。PureCoverage 很大程度的简化了检查代码覆盖率的任务,这使识别哪一部分的代码已经或者还没有被测试变得非常简单。

就像我们在这个系列的第 6 部分提到的那样,我们的单元测试工作几乎与核心的软件开发本身开始的一样早。我们多数的开发人员在他们拥有一个能够被测试的软件单元不久就开始编写单元测试。他们喜欢当代码在他们的头脑中产生时测试软件的内部构件。

单元测试的执行总是先于系统的构建;将明显能够通过单元测试来消除的简单缺陷引入到一个构建版本中是让人不可接受的。单元测试总是在代码被分发检查之前被执行。此外,开发人员以规范的基础运行他们的单元测试以确保他们的定期变化不会破坏软件。我们的方法不像一些软件方法那样激进 €€ 比如 极限编程(XP),在 XP 中单元测试的开发通常是先于代码的开发的 €€ 但是我们将单元测试当作是一个重要的软件开发的早期步骤。

自动化的能力 51Testing软件测试网JmI&nP
这里当然也有一些如何进行测试的问题,特别是什么样的测试应该被自动化的范围。编写“后台”(非 GUI )代码的开发人员是幸运的,他们能够编写自动化的测试,包括 Java 驱动程序、代码存根和脚本。然而,就像我们早些时候提到的,GUI 开发人员的测试是更加困难的。

对于我们的非 GUI 测试,我们观察了与每一个类相关联的单元测试的习惯;我们编写驱动代码访问类,并报告成功或者是失败。我们尝试使用能够为我们自动生成、管理和运行测试的测试框架,比如被 XP 所推荐的那些工具,但是他们将产生混杂的结果。虽然理论是很好的,但是这些框架(包括,比如 JUnit)对于我们的项目目的来说来是不够成熟的。不过,我们的开发人员非常自信如果他们有时间熟悉和对这些工具进行改进,这些测试框架对我们的单元测试是非常有价值的。我们也许在将来的项目中更多的使用这些测试框架。在我们的 ASDI 项目中,采用 XP 的方法也许是太冒险了;相反,我们更加愿意接受 XP 在控制和风险降低方法方面的概念和思想。你能够在 the XProgramming.com 网站上找到大量有关 XP 思想的内容。

我们没有使用 Rational 的测试工具来测试非 GUI 的代码,因为我们觉得他们不能达到一个足够底层的级别。对于自动化测试我们的 GUI 驱动的代码,Rational 的测试工具真的表现的非常出色。用户界面测试是非常手工和交互的,并且要求大量的内容确认; Rational 的测试工具以一种一致的并快速的方式使我们反复的进行这些测试变得更加的简单容易。

代码覆盖率
?+y#y7Tx216511通过使用 Rational PureCoverage ,在我们的单元测试执行期间,我们能够大幅的降低我们花在确定代码覆盖率上的时间 €€ 也就是说,哪些方法或者代码行被执行或者被遗漏 。这个工具能够使我们观测我们提供的代码覆盖测试,然后决定是改进测试还是通过手工检查的方法来测试代码。

PureCoverage 除了可以支持 C 或者 C++ 的应用程序以外,还可以支持 Java 程序,并且可以通过与 Quantify 相同的方式来配置和运行(在这个系列的第 6 部分被讨论过)。这个工具能够使我们浏览我们的单元测试;以两种方法进行代码覆盖测试:使用 Coverage Browser 或者指定文件的 Coverage Fileview 方式。

使用 Coverage Browser 的方式(图 1 ),我们能够看到在单元测试中被包括的每一个文件(和目录)的代码覆盖测试的统计学的总结。这些统计表包括了所有方法的调用次数,方法被访问或者遗漏的次数,还包括被访问或者遗漏的代码行的数量。

图 1: Coverage Browser
(点击放大)

我们能够双击一个在总结中的方法来进入 Coverage Fileview ,仅仅显示在那个方法中哪些代码行被访问或者被遗漏。就像被显示在图 2 中的例子,被遗漏的代码行被用红色突出出来(被访问的代码行用蓝色标识)。

图 2: Coverage Fileview
(click here to enlarge)

功能测试 51Testing软件测试网 I5W7ci4K5O
功能测试根据被定义在用例中的需求来验证软件是否正确的工作。为了确保我们测试了所有的需求,我们在设计和组织我们的功能测试时使用 Rational Robot 和 Rational TestManager 。(一个关于使用 Robot 的功能测试策略的讨论能够在 Robot 的用户指南中被找到。)Robot 能够使测试脚本更加容易的被录制,然后为自动化测试回放。使用 Robot 能够创建两种类型的测试脚本:

  • GUI 脚本 记录你的用户界面动作,当进行回放时,就像一个用户在操作应用的登陆和控制程序的窗口。一些客户端的测试 €€ 比如,嵌入到我们的 Web 应用中的 ActiveX 控件 €€ 需要使用这些脚本。因为 GUI 测试为我们造成了特殊的问题,因此这类的功能测试将在下一部分被详细的讨论。
  • VU scripts 当你使用它在包的级别上跟踪什么样的网络信息被发送和接受时,检测你的应用。当进行回放时,这些脚本不必登陆应用就可以重新运行测试,这使他们比 GUI 脚本执行的更快。我们为我们的 command gateway 的非 GUI 功能测试和 B2B 的负载测试使用 VU 脚本。

我们尽可能早的开始创建我们的功能测试集合,因为这些测试对工程团队来说是非常有价值的工具。我们在代码被分发检查之前适当的拥有测试脚本的目标有时是很难实现的,可能是因为代码的一些部分和一些组件要比其他的代码和组件花费更多的时间来完成,或者是因为集成和测试(I&T)团队太慢以至不能及时的完成测试脚本。在一种情况下,当用户界面仍然在变化时,测试脚本已经被完成了;虽然一些返工是必要的,但是变化的出现是相当容易集成的。

一旦我们拥有了一个强有力的功能测试集合,重新测试系统将是非常容易的。这样当你需要在后来的迭代中重新测试系统小的改变时得到很大的回报,并且可以确保变化不会影响其他的代码部分。我们映射我们的功能测试脚本到用例上,以便我们可以立即知道当被关联到被给定的用例的需求被修改时哪一个测试应该被运行。

GUI 测试 51Testing软件测试网7@2YF1TN"i|2g0u|6R
当非 GUI 代码的开发人员非常高效的进行他们的单元测试工作时,JSP/servlet 的开发人员将很难的保证时间的进度。刺痛他们的是测试 GUI 域的过程,这个过程包括反复的执行下面的步骤:

  1. 在数据库中建立测试数据。
  2. 通过 Web 浏览器登陆应用。
  3. 导航被测试的页面(一个表单要被填充)。
  4. 在页面上填写一个或者多个域,依赖具体的测试。
  5. 点击适当的按钮提交表单。
  6. 检查结果。
  7. 使用不同的测试(不同的域值或者不同的域)返回到步骤 4 ,直到所有合理的组合都被测试。

一些 GUI 测试尤其令人讨厌,包括相同的入口,在几个域中填写冗长的值。可以使用剪切和粘贴,但是对于团队来说一遍一遍的重复这些测试仍然是非常琐碎的工作。有些页面有 50 个不同的测试必须被执行,每个测试都包括很多的步骤。

虽然我们最初不倾向使用 Rational 的测试工具,但是我们觉得我们在 GUI 上的困难是我们深入研究 Rational 测试工具的很好的理由。我们决定使用 Rational Robot 来自动化我们 GUI 的大部分测试。我们通过以下的方式调整了这些测试:

  • 开发人员为每一个测试起草一个单元测试说明。
  • 初级的集成与测试团队成员接受单元测试说明并基于当前的软件构建版本创建测试脚本。
  • 单元测试脚本是可配置管理的,以便对测试脚本的变更可以被跟踪。
  • 定期的,一个开发人员给集成与测试团队执行单元测试脚本的任务,并提供一个根据单元测试说明指明成功或者失败的报告。

这个方法工作的非常好。它不仅仅在集成与测试团队没有太多的事情做的开发过程的早期阶段给他们在更多的工作,而且也给他们一个机会通过揭示单元测试说明来了解整个软件系统。此外,我们为 GUI 测试使用 Robot 的经验也为阿我们对其他的功能测试脚本进行了准备。

当 Rational Robot 启动时,它需要一个已存在项目(使用 Rational Administrator 创建的)的选择,测试脚本将与这个项目进行关联。在我们的例子中,项目的定位必须是在网络上可访问的,以便我们能够在整个团队中共享项目的数据库。我们在 Administrator 中创建了 ASDI 项目,如图 3 所示,并且当 Robot 提示我们选择一个项目时,我们选择了这个项目。

图 3: 使用 Rational Administrator 创建一个项目

一个验证测试的例子 51Testing软件测试网)W,\y9bZ(~I'at
作为一个 GUI 测试的非常简单的例子,我们需要确证对于我们的 partSearch.jsp 页面来说客户端的验证是行为正确的,这个页面执行了 JavaScript 的代码来验证他们域。每个 ASDI 的条件,部分数字被输入到整个页面中,比如,必须是比 0 要大的整型数字;如果一个用户输入一个无效的数字,JavaScript 代码就会报告一个错误,并且不会送坏的数据到服务器。我们的 JavaScript 代码遵循了在 对于表单验证的样例代码,我们在 FormChek.js 文件中编写了我们自己的验证代码。适当的使用这个代码,一个负数的输入会弹出如图 4 所示的窗口。

图 4: 适当的 partSearch.jsp 页面验证

创建测试脚本 51Testing软件测试网(i7Fa)\^*L
我们在 Robot 中创建了一个测试脚本来测试数字域的验证是否示适当的。首先 Robot 提示我们为脚本提供一个名字(图 5)。

图 5: 录制一个新的 GUI 脚本

在点击 OK 这后,我们被提供了一个录制控制器(图 6),然后当 Robot 录制我们的动作时,我们使用我们的基于窗口的应用。在这个例子中,我们启动了 Internet Explorer 5 ,在 partSearch.jsp 页面进行浏览,输入一个坏的数字 (-123456),点击 页面上的 Submit 按钮。

图 6: Robot 录制控制器

Robot 将我们的动作记录在一个 GUI 脚本中(图 7 )。这是一个非常简单的例子;我们实际的测试会包括更加复杂的测试脚本。我们不用创建成百上千个独立的脚本,而是尽量为每一个屏幕界面设计一个大的脚本。在 Robot 的文章中有进行测试设计的非常详细的信息,我们能够从 Robot 文档中所推荐的内容中得到大量的借鉴。

图 7: 简单的 Robot GUI 脚本
(点击放大)

通过使用易读的并且可以容易的进行编辑的脚本,我们就不必为只是有很小差异的测试重复的录制测试脚本了。有时我们可以不用重新运行测试就直接编辑测试脚本,或者我们只是重新录制一个测试的一小部分,然后将它粘贴到已存在的脚本中。

运行测试
z^m9MFH g216511为了再一次运行测试,我们简单的在 Robot 的录制控制器上(或者选择 File 菜单上的 Playback )点击 “play” 按钮。脚本就像我们最初执行测试一样回放我们的测试操作,并且当脚本运行完成时,Rational TestManager 被启动来总结我们的测试结果。对于上面那个简单的例子,TestManager 在图 8 中显示的结果表明,测试脚本运行的结果是测试被通过。

图 8: TestManager 报告 Robot 的测试通过
(点击放大)

假设我们想测试代码的错误处理能力,比如坏的数字不再被捕获 €€ 也就是说,没有出现一个指明错误的窗口,我们的应用就会将整个数据传送到 servlet 来执行查询。当我们通过回放脚本重新运行这个 GUI 测试时,Robot 将会捕获这个问题,并且将结果写到报告中(图 9 ),包括显示出这个测试是失败的。

图 9: TestManager 报告 Robot 测试的失败
(点击放大)

总结
f5C6H` Xu8Ip;}Q216511当我们开始 ASDI 项目时,我们期望使用 Rational 的分析和设计工具而不是 Rational 的测试工具。到项目第一阶段的这个时期,我们非常惊讶并且也很高兴的看到我们通过使用 Rational 的测试工具自动化并且改进了我们的测试过程。这些工具都有一个坚实的学习曲线,但是一旦我们掌握我们每个工具的使用方法,我们的集成与测试团队的生产力将大大的提高。在一些情况下,个体开发人员使用象 Rational Purify 、Quantify 和 PureCoverage 这样的工具为他们的单元测试工作提供补充。其他的工具,比如 Rational Robot ,则需要集成与测试团队具有更高的技能并投入更大的注意力。

计划未来 51Testing软件测试网E k7V)Dx B4N
团队仍然必须在系统级别上承担集成和测试的任务。多数的单元测试工作被分包给了开发人员,但是我们还需要更加全面和正式的测试子系统和整个系统。这就意味着我们需要正式的构建版本、最终的构建文档和在集成与测试上的重要关注。特定目的的负载测试只是我们测试工作中的一小部分,但是它在整个系统的测试中却是非常重要的。幸运的是,我们的测试集合已经完成了 95% ,并且我们还稍稍的比计划的时间提前了一点,因此我们能够有一些额外的精力来关注系统的测试以确保高质量的第一阶段的系统交付。

主要风险
8X2sC/JfB'Y.uV216511

我们的风险列表在此刻已经非常的短了。客户在演进系统上的合作并不太令人惊讶,我们的技术风险已经非常少了,非常感谢工程团队带来的良好的进展。

现在我们必须对我们的代码开发进行最后的加工、执行系统的测试、识别系统中的任何缺陷并按计划交付阶段一的系统给客户。当团队接近主要阶段的尾声时,及时的将所有的细节包装起来通常时很难的。如果我们想避免超出计划,我们就需要系统有少量的缺陷,并且能够快速的矫正在测试中发现的任何问题。

关于作者

Steven Franklin 在软件的设计、架构和工程过程方面有非常广泛的背景,这些经验通常被用到大的,分布式的信息管理和控制系统中。他从1997年开始使用 Rational 工具,他主要的兴趣在 XML 、J2EE、无线和软件工程技术方面。你可以通过 steve@sfranklin.net联系 Steven.

评论

相关推荐

Global site tag (gtag.js) - Google Analytics