背景
公司里没有专门负责测试的同学,日常的测试工作都是开发的同学兼顾。随着项目规模的扩大,迭代开发后的回归测试已经很难覆盖到所有功能点,尤其是公共组件的升级更容易导致线上事故。这时候我们希望有一个支持 Web 项目的验收测试方案,保证每次开发后项目的核心功能不会出现问题。
选型
这里先要提测试界两个鼎鼎大名的项目。
- Selenium, 浏览器自动化工具,可以驱动浏览器完成定制的操作。
- Phantomjs,一个基于 WebKit 的 JavaScript API。除了没有可视化界面,可以完成浏览器的几乎所有操作,访问网页并支持运行 Javascript。因为不需要启动浏览器,所以经常被用于轻量级测试方案。
在选择哪一个测试框架的时候,我确实纠结了一番。计划中的测试项目上线后,所有的开发同学都应该参与维护。产品功能如果有变更,负责开发的同学也要更新相应的测试用例。从这个角度来讲,负责交互实现的前端同学维护测试项目的机会最多,所以本来希望使用基于 Node 的解决方案,比如 Jasmine,Mocha,以减少前端同学的上手难度。
不过经过调研,最终还是选择了 Ruby 社区的 Capybara。
先摘录 Capybara 官方描述的优势。
- No setup necessary for Rails and Rack application. Works out of the box.
- Intuitive API which mimics the language an actual user would use.
- Switch the backend your tests run against from fast headless mode to an actual browser with no changes to your tests.
- Powerful synchronization features mean you never have to manually wait for asynchronous processes to complete.
其中让我评价最高的是第三条,可以很方便地更改测试实现。开发同学在本地环境跑测试的时候,最直观的方式莫过于通过 Selenium 启动浏览器来观察;此外我希望将自动化测试融入到上线流程中,在没有 UI 的服务器上运行测试,这就需要支持 Phantomjs 的测试方案。Capybara 正好符号要求,只用一个配置项,就可以切换具体的测试驱动。
第一条和第二条不再赘述,解释下第四条。在 Web 页面中难免有 Ajax 请求,我们的测试预期很可能是基于这些异步请求结果的。如果正常写代码,我们不得不手动设置等待时间,来获取异步请求的返回结果。Capybara 帮我们完成了这个过程,只需要按顺序写你期望的操作就可以了。但是在实际开发过程中,发现 Capybara 的这个特性有时并不好用,有时还是得手动 sleep:(
总结
- 如果前端交互比较复杂,开发 UI 测试用例会比较费时,同时产品变化也会带来测试用例后续的维护成本。建议一开始只需要检查产品页面是否能正常渲染,有没有 5xx 和 Javascript 报错,这样开发量不大,并且就已经能规避很多问题了,是一件投资回报率很高的事情。
- Capybara 支持 Cucumber,RSpec 等 BDD 测试框架。个人认为在测试项目不是很重的情况下,使用 Test::Unit 足以。
最终一期的测试工程覆盖了线上项目核心功能的交互,以及所有课程类型页面的检查。自动化测试流程也整合到上线操作中,测试不通过会终止上线操作。投入运行后的第一个月内规避了三次线上事故。