关于单元测试
单元测试是保障程序按照预期逻辑执行的一种测试方式,现在也逐渐被应用到前端项目。我刚开始写JavaScript的时候每次测试都要启动浏览器调用一下需要测试的代码,甚至还需要模拟一些数据来达到效果,最后这些测试的代码片段会被删除。但是bug出现的时候不得不在页面中重新写测试代码,非常费时。
事实上单元测试已经非常的成熟,包括赫赫有名的YUI test,今天我们介绍jQuery团队开发的QUnit单元测试框架,目前jQuery的测试正是使用这个单元测试框架,如果感兴趣可以到github上看看jQuery的test内容
准备
QUnit框架实际上就是一个JavaScript文件还有一个css文件,从官网http://qunitjs.com/下载引用或者直接使用cdn镜像
http://code.jquery.com/qunit/qunit-1.12.0.css
http://code.jquery.com/qunit/qunit-1.12.0.js
简单示例
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!-- 引入QUnit -->
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.12.0.css" />
<script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.12.0.js"></script>
<!-- 引入QUnit END -->
</head>
<body>
<h1 id="qunit-header">QUnit测试</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<script>
// 定义一个判断类型的函数
var type = function (param) {
return typeof param;
};
// 开始测试
//定义测试模块(可选)
module("类型判断");
// test开启一个测试
// 参数一,随便写,用于生成报告标识
// 参数二,匿名函数,里边写测试代码
test("type()", function () {
// equal API:判断返回值与假定的值是否相等
// 第一个,设定的值,第二个调用函数返回的值,第三个参数说明 (可选)
equal("string", type("a"), "字符串等于string");
equal("number", type(1), "数值等于number");
// 实际null等于object, 这里故意写错,看看测试效果
equal("false", type(null), "null等于false");
});
</script>
</body>
</html>
使用浏览器打开页面,测试效果:
非常详细的测试信息,标红那部分就是我们要关心,null的typeof值等于object,而我们给的值是false于是测试有错误,修改一下,测试就通过了。
一个页面可以有多个测试
上面只是非常简单的,来个稍微复杂点的
// 定义一个判断类型的函数
var type = function (param) {
return typeof param;
};
// 定义一个判断是否存在数组的函数
Array.prototype.isIn = function (param) {
var i, k;
for (i = 0, k = this.length; i < k; i++) {
if (this[i] === param) {
return true;
}
}
return false;
};
// 开始测试
//定义测试模块(可选)
module("类型判断");
// test开启一个测试
// 参数一,随便写,用于生成报告标识
// 参数二,匿名函数,里边写测试代码
test("type()", function () {
// equal API:判断返回值与假定的值是否相等
// 第一个,设定的值,第二个调用函数返回的值,第三个参数说明 (可选)
equal("string", type("a"), "字符串等于string");
equal("number", type(1), "数值等于number");
equal("object", type(null), "null等于false");
});
//定义测试模块(可选)
module("数组模块");
// test开启一个测试
// 参数一,随便写,用于生成报告标识
// 参数二,匿名函数,里边写测试代码
test("isIn()", function () {
var arr = ['a', 'b', 'c'];
// equal API:判断返回值与假定的值是否相等
// ok API:判断返回值是否为true
// 第一个,设定的值,第二个调用函数返回的值,第三个参数说明 (可选)
ok(arr.isIn("a"), "a存在数组arr里");
ok(!arr.isIn("d"), "d不存在数组arr里");
equal(true, arr.isIn("b"), "b存在数组arr所以返回true");
});
// test开启一个测试
// 参数一,随便写,用于生成报告标识
// 参数二,匿名函数,里边写测试代码
test("isIn()", function () {
var arr = ['a', 'b', 'c'];
// equal API:判断返回值与假定的值是否相等
// ok API:判断返回值是否为true
// 第一个,设定的值,第二个调用函数返回的值,第三个参数说明 (可选)
ok(arr.isIn("g"), "g存在数组arr里");
ok(arr.isIn("c"), "c存在数组arr里");
});
执行结果
最后
事实上,JavaScript的开发应该单元测试通过以后在构建发布的,因此项目部署上基本都有一个文件夹存放源码,比如src,然后有一个测试的文件夹,如test。然后test里的测试文件与src源码里的文件一一对应。如果你使用grunt来构建你的项目还可以把QUnit整入你的grunt中更省事。但我觉得QUnit的测试页面写的很漂亮,还不如直接用浏览器访问好。
关于QUnit更多的API可以访问 http://api.qunitjs.com/