自动化
功能测试,或用户界面(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”。在测试本身解决数据需求是唯一的时候,这是一种高雅有用的方法,在任何合理的测试工具或者框架中同样 的方法应该有效。
优良测试的优良设计
这些只是一些例子,协助确保自动化测试强力并可维护。很多其他的例子也存在,每一种自动化测试工具或者框架都有优良的设计实践单独针对工具。