自动化功能测试,或用户界面(UI)测试,以难以维护而著称,而且没有足够的能力找出缺陷。然而,在大多数情况下出现故障的原因不是测试工具或者测试框架,而是个别测试本身跟踪设计不良。
下面有七个功能测试设计技巧,让UI测试更加可维护和更强力。
不要只是点击 要检查后续状态
很多自动化测试工具包含一个特性,就是可以自动记录一系列动作,然后回放。尽管这样的记录/回放功能在创建测试时容易驾驭,但是单纯的记录/回放动作会导致不良测试。具体而言,记录/回放测试并不会检测应用中操纵元素后的应用状态。
点击、键入、选择以及其他的功能都会以某种方式改变应用的状态。好的测试会在应用中操作元素后检查本身的结果。如果自动化测试跟随一个链接,就要让测试检查结果页是否正确。如果测试生成一个报告,就要检查报告内容是否正确。
等待,请勿停止
通常,一个应用在结果可以用测试检查之前需要一些时间。这一点在Ajax在Web浏览器调用中尤为普遍。简单地进行测试停止或者在检查这样的结果之前休眠几秒是很吸引人的,但是停止或者休眠是不良实践,如果应用用过长时间返回,然后测试就会生成错误失败。如果应用更快地返回,然后测试在转移的过程中就是浪费时间。
取代停止或者休眠,让测试等待应用的具体方面出现了。这不仅仅让测试减少错误失败的倾向,而且也导致了更强的测试,因此测试根据生成的测试等待方面,实际等待检查应用结果。
使用分离定位 不是索引
做测试的时候要是像“点击这个页面上的第三个链接”或者“选择列表上的第五个元素”这样就更好了。代替根据索引操纵应用的具体方面,为这样的元素找出或者创建唯一识别符值得努力。
如果命令链接改变了,或者命令列表改变了,测试就会导向一种预期外的路径,维护这样不可预知的测试相当难。
用正则表达式检查排列次序
应用以正确的序列显示给用户非常重要。无论是表格的列数还是列表的元素,或者是页面本身的文本,自动化测试检测事物正确的排列很重要。
这有一堆事情应该以“一”、“二”、“三”的顺序出现。测试可以使用类似的正则表达式检查出这些事情序列。下面是一个使用简化的正则表达式“glob”的例子,“glob”在Selenium以及其他自动化测试工具中可用:
|
以下是引用片段:
| getText | glob:one*two*three |
| click | sort_thing |
| getText | glob:three*two*one | |
这个测试检查的第一步是输入文本“one”,随后是文本“two”,然后是“three”。“*”表明测试允许“one”"two""three"之间任意的字符。测试第二步点击导致“one”“two”“three”倒序排列,然后测试第三步检查这个排列是否成功了。
一次且仅一次
正如上面所指出的,在应用中等待一个元素出现是较好的实践。通常这样的例子中一旦元素出现,测试会希望操作这个元素,实例就是点击。这是抽象通用动作到期自己的方法或者模型的最佳实践,然后测试按需调用这些动作。下面是一个例子,在Fitnesse和Selenium语法中wait-for-and-click抽象。
|
以下是引用片段:
!| scenario | Wait for and click | elementLocator |
| waitForElementPresent | @elementLocator |
| click | @elementLocator |
So from a test itself we need only write:
| open | www.foo.com |
| Wait for and click | link=Welcome to Foo! | |
这个例子中仅节省了一行键入,如果“Wait for and click”在测试套件中执行了数百次或者数千次,可维护性和可读性。另一个动作例子就是抽象到期自己可能登陆的模型,选择列表中的所有元素,为一系列错误做检查。
不要使用条件语句
有时,测试环境具有不可预见性。在这样的案例中,在测试中使用条件语句很诱人,例如“if
this element exists, click it, if it does not exist,
do something else.”这种方法会存在很多问题。一个问题就是类似使用索引代替具体定位器导致的问题:如果应用测试改变,自动化测试将会以完全不可预期和位置路径传下去,导致错误失败(或者更糟糕的是错误成功),让维护更加困难。另一个问题是条件语句声明的一个分支(错误地)出现在一起,测试在引入时从未显示一个缺陷。
使用Javascript创建可重用随机数据
最后,下面是使用Selenium和Fitnesse,进行具体的测试数据最佳实践的例子。在这个例子中,测试需要输入唯一的Social
Security Number,然后检查SSN是否实际上输入到应用中:
|
以下是引用片段:
| type; | ssn | javascript{RN =Math.floor(Math.random()*9999999);while (String(RN).length < 8) { RN=RN+'0';}} |
| $SSN= | getValue | ssn |
| click | link=Save |
| type; | search | $SSN |
| GET SEARCH RESULTS CONTAINING THE SSN | |
Selenium会内嵌评估Javascript。这种测试的首行键入域ID值为“ssn”,在运行中生成随机的9个数字,通过评估Javascript作为type()动作的证据。第二行使用Fitnesse功能来存储来自“ssn”域的9个数字,称之为“$SSN”。然后测试输入九个相同数字到这个域,其ID值为“search”。在测试本身解决数据需求是唯一的时候,这是一种高雅有用的方法,在任何合理的测试工具或者框架中同样的方法应该有效。
优良测试的优良设计
这些只是一些例子,协助确保自动化测试强力并可维护。很多其他的例子也存在,每一种自动化测试工具或者框架都有优良的设计实践单独针对工具。
|