虚拟座谈:JavaScript 单元测试现状

阅读数:4423 2011 年 9 月 1 日

话题:JavaScript架构语言 & 开发

不管使用什么编程语言和平台,编写单元测试都是被广为接受的技术实践,以便交付易于维护的代码。这对于 JavaScript 这样的动态语言尤为重要,目前已经有一些针对 JavaScript 的单元测试框架和库供大家选择。

InfoQ 与目前流行的一些 JavaScript 单元测试框架的作者进行了问答,问题主要针对他们的项目以及开发人员可以从中获得哪些好处。

参与者包括: 

  • QUnit的作者 Jörn Zaefferer
  • Jasmine的作者 Davis Frank
  • Jarvis的作者 Tommy Montgomery
  • jfUnit的作者 Felipe Nascimento de Moura

InfoQ: 你的项目是做什么的,和其他 JavaScript 测试框架有什么不同?

Jörn Zaefferer : QUnit 是一个 JavaScript 单元测试框架,主要用于在浏览器中运行单元测试。虽然这个项目从属于 jQuery,但却不依赖于 jQuery,也不依赖于浏览器 DOM。因此你也可以在 node.js 或 Rhino 上使用。QUnit 很容易学习,你只需在 html 页面中包含两个文件,不需要安装或者构建任何其他东西。最短的测试集只需要一个 11 行的 html 文件。

Davis Frank: Jasmine 是一个 JavaScript 测试框架,目的是将 BDD 风格引入 JavaScript 测试之中。至于区别嘛,我们的目标是 BDD(相比标准的 TDD),因此我们尽 力帮助开发人员编写比一般 xUnit 框架表达性更强,组织更好的代码。此外我们还力图减少依赖,这样你可以在 node.js 上使用 Jasmine,也可以在浏览器或移动程序中使用。

Tommy Montgomery: Jarvis 是一个 JavaScript 单元测试框架,API 风格基于.NET 平台上的 NUnit。与其他测试框架的区别包括堆栈打印,带颜色的字符串比较,以及可读性更好的 API。

Felipe Nascimento: jfUnit 的主要特点是它的加载方式和编写方式。它需要更少的输入,这让你编写单元测试更容易,而且可以在开发环境、控制台或任何你需要的地方运行。 

InfoQ: 能大概说一下项目的架构么?主要的组件有哪些?

Jörn Zaefferer: QUnit 的 API 非常直观: 调用 test 方法,传入测试的名字和回调函数,在回调函数中编写测试代码,其中包含一些断言。QUnit 还提供一些选项来组织测试,例如含有 setup 和 teardown 的模块。在内部这些调用被映射为队列。根据执行环境的不同,QUnit 会在 window.load 或其他事件发生时(或者由用户触发)开始执行测试。当某个测试需要异步执行时,会等到测试执行结束后再执行下一条。测试的执行顺序是变化的: 这是一个可选的功能,默认会根据上一次执行的结果重新排列执行顺序,但结果还是按照之前的顺序显示。如果你选择隐藏已经通过的测试,就可以重新运行所有失败的测试,无需等待将全部测试都运行一遍的时间,可以更快知道这些测试是否被修复。

Davis Frank: 我们尽量保持简洁,Jasmine 的核心只有一个 JavaScript 文件,它提供了一种领域专用语言来编写测试。这种领域专用语言将测试组织为树状结构并执行。这个部分非常的简单。

在核心部分之上,还有一些用于在不同环境中显示测试报告的功能,以及方便管理源文件和测试文件的功能。Jasmine 可以在 Ruby on Rails 或任何 Web 框架中使用。还有些人用它在 node.js 环境中做开发,任何使用 JavaScript 的地方,Jasmine 都应该能够使用, 如果不能我们就要让它变成可能。

Tommy Montgomery: 和其他 xUnit 框架一样,Jarvis 也是基于约束的。每个断言其实都在背后创建了一个约束对象,用来比较期待值和实际值。例如,当运行 Assert.that("foo", Is.equalTo("bar")); 时,会对左边的“foo”和右边的“bar”做等值比较。这个 API(从 NUnit 借鉴而来)非常简单易读,我认为这在单元测试中是非常重要的。在使用方面,主要的组件是 Assert 对象、Is 对象和执行器。Assert 暴露一组函数用于对值进行断言,Is 则体现了 Jarvis 基于约束的架构。你可以通过调用 Jarvis.run() 并传入测试函数来运行测试。Jarvis 的测试报表是可配置的,内置两种报表方式:一种针对控制台(比如 FireFox 中的 Firebug),另一种则生成 HTML。

Felipe Nascimento: jfUnit 是一个全局对象,你可以通过它来添加或删除测试。写好测试以后,这些测试并不会自动执行,你需要显式调用 jfUnit 的执行方法,在控制台或地址栏里都可以。我建议你在开发环境和测试环境中自动加载(测试库本身和测试脚本),在生产环境中则要删除。这么做可以让你在任何地方执行测试,并马上在屏幕上得到结果。

InfoQ: 开发人员刚开始使用你的框架时,怎么使用最好,典型的流程是怎样的?

Jörn Zaefferer: 网上有一篇很棒的文章introducing QUnit on Script Junkie - 覆盖了对 QUnit 的基本介绍、大多数的 API,以及一些让你可以更高效的进行 TDD 的高级特性。

Davis Frank: 有很多截屏视频和教程。这个Railscasts的非常棒,PeepCode 的CoffeeScript cast也不错,虽然是关于 CoffeeScript 的,但 Geoffrey 同时也展示了如果使用 Jasmine 来做 TDD。

Tommy Montgomery: 最好的办法是浏览 Jarvis 的网站,看看示例代码,在网站上直接执行一些测试,搞明白测试的写法以及测试报告的样式。Jarvis 本身的测试也是用 Jarvis 编写的,你可以在这里查看测试结果。之后,你就可以下载整个框架,然后在项目中使用了。编写测试的具体流程取决于开发人员,Jarvis 对此没有任何假设和约束。由于主要的测试运行器是基于 HTML 的,因此打开浏览器是必须的。我个人的工作流程是编写代码,然后编写测试,刷新浏览器,查看测试结果,如此往复。

Felipe Nascimento: 你可以在这里找到一些详细的信息。基本上,开发人员需要加载这个库,然后使用 jfUnit 对象来编写测试。测试编写完毕后,执行 jfUnit.run() 来查看测试结果。你还可以用 jfUnit.config({...}) 来设置一些参数或者环境变量。唯一我觉得需要特别提出的是,测试框架使用 body 元素来构建测试报表,因此在页面上必须要有 body 元素。

InfoQ: 哪些特性是你希望将来能够实现的?对于 JavaScript 测试框架,未来的发展方向是怎么样的?

Jörn Zaefferer: 目前最重要的是能与命令行做更好的集成,比如在 node.js 里,你需要一个 qunit.js 之外的脚本,我们会通过 npm 发布。除此之外我们会集中精力改进现有的功能。可能最后会有一个 BDD 风格的包装,比如Pavlov。那时想用 QUnit 但是又喜欢 BDD 的人可以联合使用 Pavlov 与 QUnit。最后,不算是代码上的功能,qunitjs.com 会在年内上线。

Davis Frank: 在 Pivotal Tracker 上我们有一个公开的特性计划表,你可以看到我们接下来的发布会包含哪些内容。我们欢迎来自社区的任何贡献者,但同时我们也很挑剔。我们希望能够保持 Jasmine 精炼和紧凑。让你的补丁和特性足够简洁,而且要包含相应的测试。毕竟,Jasmine 是一个测试框架,所以你最好用 TDD 的方式。

Tommy Montgomery: 目前我在努力支持 nodejs 以便可以在服务器端编程中使用。以后可能会有一个 ant task 和一个控制台的执行程序。JavaScript 测试框架对浏览器的依赖阻碍了自身(大多数情况下)。因此摆脱浏览器单独使用对所有 JavaScript 单元测试框架都是必须的。JavaScript 测试框架会更好的填补服务器端与客户端测试之间空白。

Felipe Nascimento:我非常喜欢 JavaScript,我认为这种语言将会被大多数开发人员所使用。我喜欢 JavaScript 的表达方式,新工具以及新技术。我是 BrazilJS(巴西 JavaScript 协会)的一员,我希望 JavaScript 拥有美好的前景。我很期待开发新功能,使这个测试工具将来可以让测试 Ajax 更简单,让用户编写测试更简单,让测试图形界面比如填写表单、提交表单、点击按钮(目前已经可以实现,但是比较难写)等更简单。我还想说,如果你是一个开发人员,想要贡献你的一分力量,请告诉我。请将你的批评、建议、想法、缺陷报告或者代码通过我的 github 帐户告诉我。

座谈嘉宾

Jörn Zaefferer 居住在德国科隆,是一个自由职业的 Web 开发人员、咨询师和培训师。他将 jQuery 的测试套件演化为 JavaScript 测试框架 QUnit,并且一直维护。他还创建并维护着大量流行的 jQuery 插件,作为 jQuery UI 开发组长,他关注最多的是新插件、新部件和新工具的开发。

Davis Frank 生活在北加利福尼亚,他是一位软件工程师、父亲和棒球爱好者。目前他是 Pivotal Labs 的软件工程师和经理。业余时间,他喜欢和家人在一起,并确保家里的网络保持 99.9% 畅通。

Tommy Montgomery 拥有数学及计算机学士学位。早期工作于 LAMP 项目中,去年开始将主要精力放在.NET 项目上。PHP、C# 和 JavaScript 是他最感兴趣的编程语言。近期参与的项目包括Sunlight - 客户端语法高亮程序、Jarvis 和Butterfly - 用.NET 和 JavaScript 编写的 markup 到 html 的转换程序。

Felipe Nascimento de Moura 生活在巴西,是一位资深开发人员与系统分析师。他拥有 7 年 Web 开发经验,是很多开源项目的发起者,例如 theWebMind.org、PHPDevBar,以及 jfUnit,还是巴西 JavaScript 协会 BrazilJS 的组织者之一。

更多关于JavaScript单元测试的文章,尽在 InfoQ。

查看英文原文: Virtual Panel: State of the Art in JavaScript Unit Testing