六个月前,开始推广BDD。时至今日,已经有了1200个情景(Scenario)。如果把每个情景,当做一个自动化测试用例,那么短短半年,我们已经从无到有,开发了1200个测试用例。在没有BDD的过去五年中,我们一共才开发了2000个自动化测试用例。粗略地计算下:
● 过去2000/5=400个/年
● 现在1200/0.5=2400个/年
即BDD使我们的自动化开发效率,提高了五倍,是原来的六倍。(等我先我自豪一下,hiahia。)
越多越慢
慢着!还不能高兴地太早。高效的自动化开发,带来了新的问题。突然一下子多起来的测试用例,让自动化执行时间变长了。每次的nightly build/test的时间,竟然已经接近12小时。如果加上双平台,那么跑上一轮自动化测试,要整整等上一天才能知道结果。在推广持续集成的现在(推广CI的博客,我会陆续登出),只要有代码提交,便运行的自动化测试,竟要耗上一整天,才能对提交的代码有一个反馈?!这不管对测试人员,还是研发人员,都是不可以接受的。
自然,最简单的解决办法,少跑。从每个Feature(功能)中,精心挑选出最基础的Scenario(场景),每次只运行这些基础的场景。这样子,便无法叫做回归测试,顶多算是验收测试,或者冒烟测试。这个做法,大家说的烂大街了,挑呗,没啥难的。
可我不偏不要烂大街!自动化测试开发的意义,就是要多跑!多测!不间断地验证提交代码的正确!回归正确!要真是写了个脚本,一个礼拜跑一次,那也太金贵了!因此,一场轰轰烈烈的为自动化测试提速的运动展开鸟。
以下按照提速有效性,降序排列,越往后,提速越小。
提速法1:降低Setup/Cleanup的层次。
举一个在Eclipse的workspace中创建Java文件的例子。
Scenario: create java file in ws |
02 | Given I have an Eclipse workspace |
03 | When I create a new java file with name "Student" |
04 | Then eclipse should create a file with name "Student.java" as: |
|
修改前,此处的step:
Given /^ I have an Eclipse workspace$/ do |
2 | eclipse.new_workspace() |
|
但是,当测试用例变得越来越多时,每个用例都需要"Given an Eclipse workspace",这时候,就要思考一下,有没有什么底层的,快速的办法,生成一个空的"workspace"呢?答案是,直接写文件。因此,我们大可以将上述step,改为:
Given /^ I have an Eclipse workspace$/ do |
system( "cp -r #{$empty_ws} ." ) |
|
以此类推,需要“delete_user”的地方,大可以直接delete database,甚至可以使用数据库镜像与回滚(db snapshot/rotate)的工具。理由:我要测试的步骤是“create a new java file”,而前后的步骤,只是我所需要的环境。搭箭环境的步骤,以快,准,稳为原则,尽量避免免调用系统接口浪费资源与时间。
提速法2:提高Setup/Cleanup的层次。
在降低了部分Setup/Cleanup的层次后,我们会发现,有些Setup/Cleanup,是不需要每一个Scenario都要运行的。如远程Login的链接,如登录Web页面的链接等等。hook.rb中,可能表现为:
2 | @cli = Cli.login(host, user, password) |
3 | @web = Web.login(url, user, password) |
|
这些链接是属于无状态的,并不会因为这次提交了某个cmd,或者http request而影响链接本身。为了避免重复登录、退出,可以在一开始(所有Scenario开始前)就登录,而在结束后(所有Scenario结束后)退出。改写后的hook.rb为:
这样,就避免了每次登录、退出所需要的时间。