AppLib:所有与当前测试应用相关的方法及对象在这一层定义。它包括 2 部分:
Dialogs:正如名称所示,在这一部分中,主要保存所有的对话框或其他窗口对象,以及对这些窗口上控件的操作方法。他们通过调用下一层的基本控件函数来实现。与 NetWidgets 不同,在这一层定义的方法,是与应用中具体的控件名称所绑定的,具有明确的含义,如 SetPassword();而在 NetWidgets 层中,仅仅是某一类控件的一个通用的方法而已,如 SetText()。除了窗口对象外,一些其他的经常需要乃至的对象,如应用中的菜单,工具栏等,也在这一部分定义。
Wizards:在这一部分所定义的方法,他们包含是一些基本操作的组合,用来完成某项具体的功能,如 Login()。这些功能都是大部分 Cases 需要经常调用,或者是特定的测试步骤组合。通过将它们纳入这一层统一管理,可以很方便地起到代码重用的目的。通常这些 Wizard 是对同一个 Dialog 上的操作组合,但这并不是必须的。有时候跨多个 Dialog 的组合操作在测试用例中也是很常见的,因此也需要归纳从而提高重用性。
TestCases:很明显,这是最上一层,也就是保存所有测试脚本的地方。通过调用中间 AppLib 层的方法来实现所有测试功能,包括执行操作,检查状态并记录测试结果。
在描述完整个框架的大致结构后,我们来看看这种结构的优点:
代码隔离。通过引入 AppLib 中间层,对最上层 TestCases 屏蔽最底层实现,也就是将测试逻辑与具体功能实现逻辑分开。TestCasse 层只关注具体的测试步骤,而 NetWidgets 完成最终的功能实现。通过这种方式,使得 TestCases 层的代码简单明了,可读性好;另外未来对 NetWidgets 的改变将不会对 TestCases 层造成任何影响,也就是提高的程序的可维护性。
结构清晰。各层所定义的方法及功能也十分明确。每一层仅通过调用其直接下层来实现功能,禁止跨层调用保证代码之间的多重依赖。这对编码调试或测试运行时对问题的快速定位很有帮忙。
可扩展性好。软件产品总是在不断地发展,新功能不断地引入。在使用这种三层结构的框架以后,当需要增加新的 Cases 时,只需先加入对应的对话框及窗口对象到 AppLib,然后再通过调用它们来完成代码编写。新加的 AppLib 对象不会对原有的对象造成任何影响,因为每个对象都有仅属于自己的代码文件。而原有的 AppLib 对象则可以简单地在新的 Case 中重用。
采用这样的框架,只开放相应的接口供最终的脚本开发者进行调用,会使 Case 更加简洁易读。在 GUI 界面发生变化时,也不需要对 TestCase 做任何修改,大大提高了程序的可维护性和可扩展性。
在 RFT 里的具体实现
在定义完整个测试架构以后,接下来是在测试工具中用代码加以实现。在本项目中,我们使用的是 RFT,现在,让我们来看看在 RFT 里的具体实现。
图 2. 在 RFT 里的实现
从上图可以看到,我们使用 3 个 Project 来对应 3 个不同的层,而不是象通常的项目一样,将所有的代码放在一起,层次结构通过不同的包结构来体现。这样做的主要原因是让各层之间更加独立,而且更易于管理。另一个好处是,多个 Project 的设计可以让复制和共享更加灵活。例如,当其他 Team 也想要利用 NetWidgets 时,只需要简单地将对应的 Project 共享给他们即可;而另一个 Team 如果需要某一个 Suite 来验证某项具体功能,则可以将 3 层所对应的 Project 都共享给他。