自动化!
通过使用单元测试来代替log,我们已经可以确保测试的可复用性和自我检查能力。不过我们依然做了很多体力活,这也意味着还有提升的余地。运行一个包含测试的HTML文件很容易,但是你需要注意的是,现在的web开发者不可能一整天都在一个浏览器中做测试。所以你可能会需要在3个以上平台上测试5个以上的浏览器,而且浏览器本身可能还需要测试2个版本以上。此时,运行一个HTML就不那么容易了。
前面所写的测试用例对象是针对JsTestDrive的,JsTestDrive是一个来自谷歌的JavaScript测试框架和测试运行工具。它最大的特点就是运行测试的方式。JsTestDrive运行了一个服务器来完成不同浏览器中的运行工作。理解JsTestDrive工作的最好方式就是实践一下。
假设jQuery插件位于地址src/difference_in_words.jquery.js,测试用例位于test/difference_in_words_test.js。为了运行这个测试,我们在项目根目录下添加了配置文件jsTestDriver.conf。测试文件的内容如下:
server: http://localhost:4224 load: - src/*.js - test/*.js |
你可以下载最新的JsTestDriver jar 文件。运行这个文件需要事先准备好Java环境。然后在shell中输入下面的命令:
java -jar JsTestDriver-1.2.2.jar --port 4224 |
你已经在你的机器中启动了一个JsTestDriver服务端。下一步就是让浏览器访问http://localhost:4224/capture,它会将浏览器转到一个可用的测试用例并运行。你可以在所有可用的浏览器上运行一遍。然后打开一个新的shell,进入项目目录并输入:
java -jar JsTestDriver-1.2.2.jar --tests all |
过一会你就会看到一些输出,说明测试已经运行,并展示测试是否通过。恭喜,你已经成功地在多个浏览器中进行自动化测试。如果你的机器是在网络中的其他设备,你也可以使用这个服务端进行其他平台的测试(OS X,Windows,Linux),你的iphone,Andriod或者其他设备。你也可以用简单的shell命令对其进行区分。这太令人激动了!
JsTestDriver 不仅仅是自动化测试的选择。如果你不喜欢他的assertion框架,它也可以使用QUnit,YUI Test和Jasmine进行测试。此外,Yahoo还有YETI,一个类似的工具,特别为YUI测试定制。Zakas最近也发布了YUI Test Standalone,包括了一些类似的基于Selenium Web Driver的测试运行器。
可测试性:使用测试来优化你的代码
现在,你应该开始意识到单元测试带来的省时,特别是对于JavaScript这种可能运行在多个环境下的语言。单元测试相对其他log的方式而言,不仅仅节省了更多的时间和修复成本,而且它可以提高你的信心,愉悦程度和生产力。
现在你已经决定开始写单元测试,那么你可能会为如果开始而困扰。最直接的回答就是为一些已存在的代码写测试用例。不幸的是,通常这都比较困难。一部分原因是写测试本身需要一些经验,通常第一次写都不是那么正确。然而还有一个原因是:代码本身对测试不够友好。
可测试性例子:计算时间差值
“可测试性”是一个衡量特定接口是否对测试友好的方式。一个对测试友好的接口会让外部比较方便地访问到那些有趣的部分,而且不需要请求不相关的部分,从而可以测试任意一个给定的API。换句话说,可测试性是一个衡量接口设计是否良好,是不是做到了低耦合和高内聚,这些都是一个好的方式来判断这个对象是否足够独立于其他对象,并且每个对象/函数是不是只做一件事情,并且运行良好。
作为一个可测试性的例子,我们将回到之前的jQuery插件。在我们的前两个单元测试用力中,我们想要去确保8天前的日期能返回字符串“1 week ago”,而且其他时间也可以返回更加准确细致的字符串。注意这些都不能应用在DOM元素上,我们需要创建一个元素来测试日期的差值计算和返回字符串的友好展现。
jQuery插件本身比以前更加难以测试,最大的原因就是它做了不止一件事情:他计算了两个日期的不同,生成一个友好可读的差值展现并且从一个元素中读取日期并用innerHTML写入到DOM节点中。