好象这篇文章的原始链接来自cssrain,不记得了。。如果作者看到,请联系我一下,我加上链接,SORRY了。
文章来自google doc,内容如下:
QUnit是jQuery团队开发的 JavaScript单元测试工具,使用方便,界面美观。近期试用了一下并进一步了解了JavaScript单元测试,记录一下所思所得。
什么是单元测试
为什么 JavaScript需要单元测试
由于存在浏览器解析环境、用户操作习惯等差异,前端程序的许多问题是无法捕捉或重现的,现在前端程序的测试多是黑盒测试,即靠点击点击点击来寻找程序bug。这种方式既费时费力,又无法保证测试的覆盖面。
同时,前端逻辑和交互越来越复杂,和其他编程语言一样,一 个函数,一个模块,在修改bug或添加新功能的过程中,很容易就产生新的bug,或使老的bug复活。这种情况下,反复进行黑盒测试,其工作量和测试质量 是可想而知的。
此外,浏览器兼容性测试是前 端程序测试的重要一环,在多个浏览器之间测试前端程序,上面说的工作量就会成n倍的增加。
为什么我们的前端程序如此脆弱?就是因为没用单元测试。。
假如使用了单元测试,上边的问题就变得很容易了,当然前提 是你要花时间去研究和编写测试用例。
根据函 数或模块的源代码,编写出包含各种情况的测试用例,每次解决bug或添加新功能,都随时更新这个用例然后进行测试,很容易就找出新bug和“复活”的老 bug。
测试兼容性,只需要在不同的浏览器 中分别运行这个测试,问题就一目了然了。
也 许白盒比黑盒要多费几倍的脑子,但想想我们那脆弱的程序,想想那些随时冒出来的烦人的老bug,费点脑子,值了!
使用QUnit
注:下面的内容主要参考了 QUnit文档 和 NetTuts+的这篇文章。
建立一个测试页面,引入 qunit.js 和 qunit.css 这 两个必需的文件,这两个文件是存放在github上的,鉴于目前操蛋的互联网环境,最好下载到本地调用。
注:body中的元素id命名必须依照如下形式,否则无法 正常显示。
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <link rel="stylesheet"href="http://github.com/jquery/qunit/raw/master/qunit/qunit.css" type="text/css"media="screen" />
- <script type="text/javascript"src="http://github.com/jquery/qunit/raw/master/qunit/qunit.js"></script>
- </head>
- <body>
- <h1 id="qunit-header">QUnit example</h1>
- <h2 id="qunit-banner"></h2>
- <h2 id="qunit-userAgent"></h2>
- <ol id="qunit-tests"></ol>
- </body>
- </html>
测试示例
下面是一个最简单的函数测试用例,解释请见程序注释。
- //定义测试模块
- module( "测试示例" );
- //定义一个简单的函数,判断参数是不是数字
- function simpleTest(para) {
- if(typeof para == "number") {
- return true;
- }
- else{
- return false;
- }
- }
- //开始单元测试
- test('simpleTest()', function() {
- //列举各种可能的情况,注意使用 ! 保证表达式符合应该的逻辑
- ok(simpleTest(2), '2 是一个数字');
- ok(!simpleTest("2"), '"2"不是一个数字');
- });
module( name, [lifecycle] ) 函数指定测试模块和周期。
ok( state, [message] ) 是QUnit中最常用的一个判断函数,只能判断true和false。
DEMO在这里,看一下测试结果:
结果都是绿的,说明两条测试语句都符合设定的规则。可以尝试修改下规则
- //...
- ok(simpleTest("2"), '"2"是一个数字');
- //...
就可以看到爆红了。。
更多测试判断
除了ok()之外,QUnit还有如下几个判断函数:
相等判断equals( actual, expected, [message] )
示例:
- //定义一个简单的函数,返回数字和2的乘积
- function simpleTest1(para) {
- return para * 2;
- }
- //开始单元测试
- test('simpleTest1()', function() {
- //列举各种可能的情况
- equals(simpleTest1(2), 4, '2 * 2 等于 4');
- equals(simpleTest(2), 3, '2 * 2 等于 3');
- });
相同判断 (包含数组、对象等)same( actual, expected, [message] )
示例:
- //定义一个简单的函数,返回一个数组
- function simpleTest2() {
- return [1, 2];
- }
- //开始单元测试
- test('simpleTest2()', function() {
- //列举各种可能的情况
- equals(simpleTest2(), [1, 2], '函数返回数组[1, 2]');
- equals(simpleTest2(), [1, 1], '函数返回数组[1, 1]');
- });
same()和意思和equals()差不多,但 same()可以判断数组、对象等的相同,而equals不能。
异步与Ajax
对于异步程序的测试,如setTimeout、 setInterval、Ajax等情况,按照上面的方法,在异步调用执行之前,测试就已完成并输出了结果。这时,配合使用QUnit提供的两个函数:stop( [timeout] ) 和 start(),也可以轻松搞定。
直接看例子:
- //异步测试
- module( "异步测试示例" );
- //setTimeout
- test('asynchronous test', function() {
- // 暂停测试
- stop();
- setTimeout(function() {
- ok(true, '完成运行');
- //待测试完成后,恢复
- start();
- }, 100)
- })
- //另一种形式
- asyncTest('asynchronous test', function() {
- setTimeout(function() {
- ok(true);
- //待测试完成后,恢复
- start();
- }, 100)
- })
- //Ajax测试
- function ajax(successCallback) {
- $.ajax({
- url: 'server.php',
- success: successCallback
- });
- }
- test('asynchronous test', function() {
- // 暂停测试
- stop();
- ajax(function() {
- // 异步调用判断
- })
- setTimeout(function() {
- //异步测试完成后,恢复
- start();
- }, 2000);
- })
了解更多