jQuery团队开发的JavaScript单元测试工具QUnit详解
本文详细介绍由jQuery团队开发的QUnit JavaScript单元测试框架。内容涵盖单元测试的基本概念与优势,QUnit的安装配置、基础语法如test与ok断言,以及module模块分组、setup/teardown生命周期管理和异步测试等高级应用,旨在帮助开发者提升代码质量与重构信心。
单元测试概述与QUnit简介
什么是单元测试?
单元测试,亦称模块测试,旨在验证程序模块(软件设计的最小单元)的正确性。它主要检验程序内部逻辑,也被称为个体测试、结构测试或逻辑驱动测试。通常由编写代码的程序员负责执行。
一般而言,程序员每次修改代码后至少进行一次单元测试。在开发过程中,可能需要进行多次测试以证实程序符合软件规格书要求且无缺陷。虽然单元测试并非强制要求,但实施单元测试对项目管理具有积极意义。
—— 维基百科 (中文,英文)
单元测试的优点
1、它是一种验证行为。程序中的每一项功能都通过测试来验证其正确性,为后续开发提供支持。即使在开发后期,也能轻松增加功能或更改程序结构,而无需担心破坏重要部分。此外,它为代码重构提供了保障,使程序改进更加自由。
2、它是一种设计行为。编写单元测试促使我们从调用者的角度进行观察和思考。特别是采用“先写测试”(test-first)的方法,会迫使我们将程序设计为易于调用和可测试的,从而降低软件耦合度。
3、它是一种编写文档的行为。单元测试是无价的文档,展示了函数或类的使用方式。这份文档可编译、可运行,且始终保持最新,与代码同步。
4、它具有回归性。自动化的单元测试可避免代码出现回归错误,编写完成后,可随时快速运行测试。
参考:
http://miiceic.org.cn/phrase/200602281036115.html
http://tech.ddvip.com/2009-06/1245992965124860.html
http://www.blogjava.net/square/articles/158103.html
javascript中单元测试框架
- jsUnit:系统化的解决方案,基于XNuit规范。如果你会使用jUnit、NUnit等框架,对这个应该会很容易上手,且包括服务器端(Java的)。http://www.jsunit.net/ 评价:非常全面,专业,适合大型企业级开发。
- Test.Simple & Test.More:这个是jQuery之父John Resig在他的著作《Pro Javascript》中推荐的测试框架http://openjsan.org/doc/t/th/theory/Test/Simple/0.21/lib/Test/Simple.html 。 评价:非常容易上手,非常简洁,适合中小型项目快速引入单元测试。
- FireUnit
这个是John Resig另起炉灶做的,在他的博客John Resig - FireUnit: JavaScript Unit Testing Extension,发布了他与Jan Odvarko合作开发的基于Firebug的扩展FireUnit。简单说来,FireUnit给Firebug增加了一个标签面板,并提供了一些简单的JavaScript API来记录和查看测试。更多http://shawphy.com/2008/12/fireunit.html。 评价:里面有Test.Simple的痕迹,呵呵,John Resig是个非常善于学习并创新的家伙。FireUnit果然在易用性上表现非常出众,非常适合基于Firebug做调试环境的前端工程师。
- QUnit
QUnit是jQuery团队开发的JavaScript单元测试工具,可以到http://docs.jquery.com/QUnit中下载评价:使用方便,界面美观。
参考: http://www.cnblogs.com/kaima/archive/2009/04/09/javascrit_unittest.html
下面我们重点来介绍一下QUnit
QUnit 介绍
JavaScript 依然需要很好的可读性,所以重构也必不可少,我们知道没有单元测试的重构是不靠谱的,有好的单元测试覆盖会让我们重构时更容易成本也更低,所以对于优秀的javascript编程人员来说非常需要单元测试框架,QUnit 是一款强大而且容易使用的JavaScript 测试框架,它被用于jQuery 与其插件的测试,同时它也同样可以测试普通的JavaScript 代码。
QUnit配置与基础使用
使用QUnit
首先我们先要http://docs.jquery.com/QUnit中找到qunit.js 和 qunit.css两个文件,Qunit的框架如下:
代码如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<link rel="stylesheet" href="qunit.css" type="text/css" media="screen" />
<script type="text/javascript" src="qunit.js" ></script>
<script>
$(document).ready(function() {
});
</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> 注:body中的元素id命名必须依照如下形式,否则无法正常显示,我们可以将要测试的内容放在$(document).ready()中。
我们先来看一个简单的例子
代码如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd%22>
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js%22></script>
<link rel="stylesheet" href="qunit.css" type="text/css" media="screen" />
<script type="text/javascript" src="qunit.js" ></script>
<script>
$(document).ready(function() {
test("一个基本测试例子", function() {
ok( true, "测试布尔类型" );
var value = "hello";
equals( "hello", value, "我们期望得到hello" );
});
});
</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> 将此文件存为html直接在本地运行,结果如下

test( name, expected, test ):加入测试去运行,其中可以包含若干断言函数,比方说ok,equals等。
ok( state, [message] ) 是QUnit中常用的一个判断函数,可以判断布尔类型,整型非零为true,字符串非“”为true。 equals( actual, expected, [message] ) 是QUnit中常用的一个判等函数 我们再来看一个稍微复杂一点的例子:
QUnit高级特性:模块分组与异步测试
代码如下:
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<link rel="stylesheet" href="qunit.css" type="text/css" media="screen" />
<script type="text/javascript" src="qunit.js"></script>
<script>
$(document).ready(function() {
test("a basic test example", function() {
ok(true, "this test is fine");
var value = "hello";
equals("hello", value, "We expect value to be hello");
});
module("Module A");
test("first test within module", function() {
ok(true, "all pass");
});
test("second test within module", function() {
ok(true, "all pass");
});
module("Module B");
test("some other test", function() {
expect(2);
equals(true, false, "failing test");
equals(true, true, "passing test");
});
});
</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( name, lifecycle ):是用于对测试模块进行分组,[lifecycle] 用于初始化测试和清理测试。
参考如下实例:
代码如下:
module("module2", {
setup: function() {
ok(true, "once extra assert per test");
this.testData = "foobar";
},
teardown: function() {
ok(true, "and one extra assert after each test");
}
});
test("test with setup and teardown", function() {
expect(3);
same(this.testData, "foobar");
}); 异步测试:
代码如下:
codeasyncTest("异步测试", function() {
expect(2);
$.getJSON("/Home/JosnDemo", function(result) {
equals(result.x, "sss");
equals(result.y, "sss");
start();
});
}); "/Home/JosnDemo"是提供json数据的地址,这里需要注意的是必须在写完断言函数后调用start()函数。
Qunit还提供了在测试时的一些更为高级的应用,比如希望在某个测试开始时做些工作等,可以参见http://docs.jquery.com/QUnit#Integration_into_Browser_Automation_Tools
JQuery的很多核心套件是使用Qunit来进行测试的,http://docs.jquery.com/QUnit#Reference_Test_Suites中有很多的例子可以供大家参考。 例子下载
生产环境怎么自动移除或禁用 Mock.js
2026-11-05 09:26:52
JS文件报MIME type mismatch错误导致加载失败的修复方法
2026-11-04 11:41:15
Auto.js下载速度慢或链接失效怎么办?国内镜像与备用方案
2026-11-03 15:46:28
Vite项目JS压缩配置指南:提升构建速度与体积优化
2026-11-03 08:53:48
JS压缩工具选型:Terser、esbuild与UglifyJS对比
2026-11-03 08:28:21
