不管使用什么编程语言和平台,编写单元测试都是被广为接受的技术实践,以便交付易于维护的代码。这对于JavaScript这样的动态语言尤为重要,目前已经有一些针对JavaScript的单元测试框架和库供大家选择。
InfoQ与目前流行的一些JavaScript单元测试框架的作者进行了问答,问题主要针对他们的项目以及开发人员可以从中获得哪些好处。
参与者包括:
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