前一阵跟同事讲 JavaScript 单元测试该如何搞起,找了些资料, 结合自己的应用情况,说了一些,但依然说得不好。因此写篇博文,记录一下。
按专业做测试的童鞋们的划分,单元测试属于白盒测试。做法是,
与待测模块使用相同的程序语言,引入该模块,引入测试框架,然后噼里啪啦写一堆测试用例。
Ruby 童鞋这一点做得很好,自带了一个 test/unit
,Rails 童鞋更进一步,在
项目根目录的 test/unit
与 test/functional
下分别会生成对应 model 与
controller 的测试类。同时还补上了一坨断言,详情请看
Rails Guides 之测试
JavaScript 短小精悍,自带的东西除了各种神奇语法,啥也没有;有一堆所谓的 Juicy Libraries 可供挑选,结果经常因为想用 B 框架的甲插件,自己却已经用了 A 框架而心生惆怅。其实兼收并蓄也没什么不好,大家网速都还可以的嘛。
扯远了哈,我的意思是,要做 JavaScript 单元测试,第一个问题就是先得挑一个框架。 StackOverflow.com 上有人弄了个 详细列表 ,有些已经陈旧了,例如 JSUnit,有些则偏整体测试解决方案一点,例如 John Resig 做的 TestSwarm.com。
我们先讲语言层面的测试框架本身好了,现在用得比较多的是 JSSpec、 Jasmine 和列表中没有提到的同是 John Resig 的作品 QUnit。
先被我排除的是 JSSpec,因为在我接触到的前端项目里头,要么没有写单元测试, 要么没有用 JSSpec,所以我一直没有见过 JSSpec 的单元测试语法是什么样的; 不过把它列入考虑的原因也简单,没有专门的测试人员的 Facebook, 写 JavaScript 单元测试用的框架就是它 (来源)。
SeaJS 与 Kissy 用的都是 Jasmine, 应该就是玉伯的偏好了。Jasmine 的语法效仿自 Ruby 里的 RSpec。 这种语法风格的宗旨是更贴近自然语言,直接从源码生成程序说明文档。
1 2 3 4 5 |
|
但我不太喜欢,觉得有点不伦不类的。另一个让我最终没选它的原因是, 测试输出的部分还得自己包装,好麻烦⋯⋯ 参考玉伯 SeaJS 代码中 runner 部分。
所以我选了 QUnit。好啦,我终于切题了,下面讲 QUnit 的用法。
QUnit 包含两个文件,qunit.js 与 qunit.css,它的断言结果是输出到页面 DOM 里的, 所以基于 QUnit 写的测试,都需要有个 html 页面,引入这俩文件,并且保证页面中有这样的 DOM 节点:
1 2 3 4 5 |
|
你的测试代码应该长这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
在测试页面中引入这个,就齐活了。
QUnit 的 示例 有很多,jQuery 本身, jQueryUI 的部分项目,都用这货做的单元测试。
基本的测试用例搞完了,接下去要考虑的事是如何 自动化, 做持续集成。我尚无实际应用经验,先按下不表。John Resig 抱怨过 JavaScript 测试的烦恼处, 多平台、多浏览器测试使得一个小改动都需要大量人工去测,因此弄了 Test Swarm,对前端童鞋来说,文章很有趣,推荐一看。
此外,淘宝UED 的云谦童鞋,去年就搞过一个云测试项目,感兴趣的童鞋可以去了解一下。