QUnit——对JavaScript 进行单元测试的利器
该文章中使用的源代码地址: http://download.csdn.net/detail/chr23899/9566957
1.QUnit下的简单测试:
简单说明(本次框架采用的是QUnit-V2.0.0版本):如上图:从左到右从上倒下一次说明如下:
a.QUnit.module()是定义当前测试用例属于哪个模块下。注意:对于V1.0.0版本中不需要QUnit,对于V2.0.0中必须添加QUnit.开始。
b.QUnit.test()是定义当前的测试用例。同样在V2.0.0中必须添加QUnit.开始。
c.Conversion to F 是定义当前测试的名称,执行测试的时候会按照这个名称进行显示。
d.function中添加了assert,这里是对assert这个模型的引入,因为在该功能中我们需要使用assert下面的equal方法。
e.convertFromCelsiusToFahrenheit 这是你要测试的js函数的方法名。
f.assert.equal后面需要跟两个参数,第一个是实际执行的值(result),第二个是我们期待他正确执行应该返回的值(expected)。需要注意的是在V1.0.0中可以直接使用equal,但是在V2.0.0中不可以。
详细说明请参考官方关于V2.0.0的介绍: http://qunitjs.com/intro/
1.在testMyScript.js中添加如下内容:
QUnit.test( "hello test", function( assert ) {
assert.ok( 1 == "1", "Passed!" );
});
2.在页面中添加qunit.js和qunit.css两个文件,同时添加MyScript.js(要测试的js文件,暂时为空)和testMyScript.js。新建test-index.html其内容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>QUnit Test Suite</title>
<link rel="stylesheet" href="css/qunit.css" type="text/css" media="screen">
<script type="text/javascript" src="js/qunit.js"></script>
<script type="text/javascript" src="js/MyScript.js"></script>
<script type="text/javascript" src="js/testMyScript.js"></script>
</head>
<body>
<h1 id="qunit-header">QUnit Test Suite</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">test markup</div>
</body>
</html>
3.测试结果:
测试成功,结果如下:
2.Qunit下的测试扩展
1.在MyScript.js文件添加如下内容:
在该文件中定义两个函数一个事将摄氏度转换成华氏度,另一个是将华氏度转成摄氏度。
function convertFromCelsiusToFahrenheit(c){
var f = c * (9/5) + 32;
return f;
}
function convertFromFahrenheitToCelsius(f){
var c = (f - 32) * (5/9);
return c;
}
2.在testMyScript.js文件添加如下内容:
QUnit.module ("Temperature conversion")
QUnit.test("conversion to F", function( assert ){
var actual1 = convertFromCelsiusToFahrenheit(20);
//equal(actual1, 68, ?Value not correct?);
assert.equal(actual1, 68);
var actual2 = convertFromCelsiusToFahrenheit(30);
//equal(actual2, 86, ?Value not correct?);
assert.equal(actual2, 86);
});
QUnit.test("conversion to C", function( assert ){
var actual1 = convertFromFahrenheitToCelsius(68);
//equal(actual1, 20, ?Value not correct?);
assert.equal(actual1, 20);
var actual2 = convertFromFahrenheitToCelsius(86);
//equal(actual2, 30, ?Value not correct?);
assert.equal(actual2, 30);
});
这时我们可以看到,这两个方法下的测试都是正确的。
如果我们把testMyScript.js中21行的20改成30,如下所示
assert.equal(actual1, 30);
刷新页面后,我们可以看到这里我们期待的值是30,但是实际获取到的值确实20,所以该测试用例执行未通过。我们通过Source中可以定位到错误发生在testMyScript.js的21行第9个字符。
首先添加一个prettydate.js文件,在其中添加如下内容:
var prettyDate = {
format: function(now, time){
var date = new Date(time || ""),
diff = (((new Date(now)).getTime() - date.getTime()) / 1000),
day_diff = Math.floor(diff / 86400);
if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
return;
return day_diff === 0 && (
diff < 60 && "just now" ||
diff < 120 && "1 minute ago" ||
diff < 3600 && Math.floor( diff / 60 ) +
" minutes ago" ||
diff < 7200 && "1 hour ago" ||
diff < 86400 && Math.floor( diff / 3600 ) +
" hours ago") ||
day_diff === 1 && "Yesterday" ||
day_diff < 7 && day_diff + " days ago" ||
day_diff < 31 && Math.ceil( day_diff / 7 ) +
" weeks ago";
},
update: function(now) {
var links = document.getElementsByTagName("a");
for ( var i = 0; i < links.length; i++ ) {
if ( links[i].title ) {
var date = prettyDate.format(now, links[i].title);
if ( date ) {
links[i].innerHTML = date;
}
}
}
}
};
其中prettyDate.format()主要是完成时间的格式化,就是把传入的时间time和时间now进行比较,如果相差的时间超过了一个月或者是负数或者为空则返回空(undefined),如果在一个月内,再做细分的比较,包括1分钟内,1小时前,昨天,几天前等等。在perttyDate.update()方法在中获取要比较的时间now,同时获取Dom树中所有a标签(超链接),如果该标签的title属性不为空,则获取title的时间进行转换。
然后添加test-time.html页面用于测试该js中的操作是否正确。具体页面内容如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Refactored date examples</title>
<link rel="stylesheet" href="css/qunit.css">
<script src="js/qunit.js"></script>
<script src="js/prettydate.js"></script>
<script>
QUnit.test("prettydate.format", function( assert ) {
function date(then, expected) {
assert.equal(prettyDate.format("2008/01/28 22:25:00", then),
expected);
}
date("2008/01/28 22:24:30", "just now");
date("2008/01/28 22:23:30", "1 minute ago");
date("2008/01/28 21:23:30", "1 hour ago");
date("2008/01/27 22:23:30", "Yesterday");
date("2008/01/26 22:23:30", "2 days ago");
date("2007/01/26 22:23:30", undefined);
});
QUnit.test("prettyDate.update", function( assert ) {
var links = document.getElementById("qunit-fixture")
.getElementsByTagName("a");
assert.equal(links[0].innerHTML, "January 28th, 2008");
assert.equal(links[2].innerHTML, "January 27th, 2008");
prettyDate.update("2008-01-28T22:25:00Z");
assert.equal(links[0].innerHTML, "2 hours ago");
assert.equal(links[2].innerHTML, "Yesterday");
});
QUnit.test("prettyDate.update, one day later", function( assert ) {
var links = document.getElementById("qunit-fixture")
.getElementsByTagName("a");
assert.equal(links[0].innerHTML, "January 28th, 2008");
assert.equal(links[2].innerHTML, "January 27th, 2008");
prettyDate.update("2008-01-29T22:25:00Z");
assert.equal(links[0].innerHTML, "Yesterday");
assert.equal(links[2].innerHTML, "2 days ago");
});
</script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture">
<ul>
<li class="entry">
<p>blah blah blah...</p>
<small class="extra">
Posted <span class="time">
<a href="#2008/01/blah/57/" title="2008-01-28T20:24:17Z"
>January 28th, 2008</a>
</span>
by <span class="author"><a href="#john/">John Resig</a></span>
</small>
</li>
<li class="entry">
<p>blah blah blah...</p>
<small class="extra">
Posted <span class="time">
<a href="#2008/01/blah/57/" title="2008-01-27T22:24:17Z"
>January 27th, 2008</a>
</span>
by <span class="author"><a href="#john/">John Resig</a></span>
</small>
</li>
</ul>
</div>
</body>
</html>
其中prettydate.format测试单元直接调用了prettyDate.format进行了测试,后面的两个prettyDate.update测试单元分别通过改变要传入的now值进行了测试。需要说明的是,我们需要测试的DOM树结构应该放在<div id=”qunit-fixture”></div>下面,这样我们在执行时会面就不会显示该区域。
这部分的测试效果如图所示:
4.小结
通过前三个部分使用QUnit进行测试后,我们发现,QUint主要是针对javascript中具体的function功能函数进行测试,同时测试中如果要操作DOM树的话,会比较麻烦。
不过QUnit的使用过程比较简单,而且功能相对强大,如果项目中存在大量的javascript函数的话,通过QUnit来测试,还是一个挺好的选择。
该文章中使用的源代码地址: http://download.csdn.net/detail/chr23899/9566957