对 JavaScript 进行单元测试的工具

澳门新葡亰网站注册 1

简介

QUnit是一个强大的JavaScript单元测试框架。他可用于jQuery,jQuery
UI和jQuery Mobile项目,以及任何使用JavaScript代码编写的项目的测试。

 简介

运行环境

  • 任何Html和JavaScript编辑器(Visual Studio 2013)
  • 从QUnit官方下载reference js和css文件

  单元测试关注的是验证一个模块或一段代码的执行效果是否和设计或预期一样。有些开发人员认为,编写测试用例浪费时间而宁愿去编写新的模块。然而,在处理大型应用程序时,单元测试实际上会节省时间;它能帮助您跟踪问题并安全地更新代码。

加入QUnit到单元测试

添加QUnit.js和QUnit.css到你要测试的HTML页面中。

<script src="//code.jquery.com/qunit/qunit-1.22.0.js"></script>
<link rel="stylesheet" 
href="https://code.jquery.com/qunit/qunit-1.22.0.css">

  常用缩略语

创建需要进行单元测试的JavaScript类

将要进行单元测试的代码放到一个单独的js文件中(Calculations.js):

// Create Calculation class.
var Calculation = function () { };

// Add Addition to method to the Calculation class.
Calculation.prototype.Add = function (a, b) {
    return a + b;
};

// Add Subtraction method to the Calculation class.
Calculation.prototype.Substraction = function (a, b) {
    return a - b;
};

// Add Multiplication method to the Calculation class.
Calculation.prototype.Multiplication = function (a, b) {
    return a * b;
};

// Add Division method to the Calculation class.
Calculation.prototype.Division = function (a, b) {
    return a / b;
};

  DOM:文档对象模型

为上面的方法创建一个单元测试用例

下面的代码就是上面JavaScript方法的单元测试用例,我们同样将它放到单独的一个js文件中(UnitTest.js):

// Instantiate Calculation class.
var c = new Calculation();
// Unit test for addition.
QUnit.test("Addition Test", function (assert) {   
    assert.ok(c.Add(2, 3) == "5", "Passed!");
});

// Unit test for subtraction.
QUnit.test("Substraction Test", function (assert) {
    assert.ok(c.Substraction(3, 2) == "1", "Passed!");
});

// Unit test for division.
QUnit.test("Division Test", function (assert) {
    assert.ok(c.Division(5, 5) == "1", "Passed!");
});

// Unit test for multiplication.
QUnit.test("Multiplication Test", function (assert) {
    assert.ok(c.Multiplication(5, 5) == "25", "Passed!");
});

  HTML:超文本标记语言

在HTML代码中引用所有的js和css文件

在HTML代码中分别创建一个id为qunit、qunit-fixture的div标记。

<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-1.22.0.css">
<script src="~/Scripts/Calculations.js"></script>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="//code.jquery.com/qunit/qunit-1.22.0.js"></script>
<script src="~/Scripts/UnitTest.js"></script>

  JSTD:JSTestDriver

QUnit测试结果窗口

澳门新葡亰网站注册 1

  YUI:Yahoo澳门新葡亰网站注册,! User Interface

  在过去,只对服务器端语言进行单元测试。但前端组件越来越复杂,使得编写
JavaScript
代码测试用例的需求日益提高。如果您不经常编写客户端脚本的测试,学习进度可能非常难。测试用户界面可能需要在思路上做一些调整。(有些程序开发人员一时半会还不能相信
JavaScript 是合适的编程语言。)

  在本文中,您将学习如何使用 QUnit、YUI Test 和 JSTestDriver 对
JavaScript 进行单元测试。

  下载 本文的源代码。

  JavaScript 单元测试

  为了演示 JavaScript 测试,这一节将分析 JavaScript
中一个基本函数测试用例。清单 1 显示了要测试的函数:将
3(作为一个数)添加到传递的变量中。

  清单 1. 源代码 (example1/script.js)

1
2
3
4
                 
function addThreeToNumber(el){
    return el + 3;
}

  清单 2 在自执行的函数中包含了测试用例。

  清单 2.测试用例 (example1/test.js)

1
2
3
4
5
6
7
8
9
10
11
                 
(function testAddThreeToNumber (){
    var a = 5,
        valueExpected= 8;
  
    if (addThreeToNumber (a) === valueExpected) {
        console.log("Passed!");
    } else {
        console.log("Failed!");
    }
}());

  将 5 传递给测试的函数之后,测试检查返回值是
8。如果测试成功,就会在一个现有浏览器的控制台中打印出
Passed!;否则就会出现
Failed!。如果要运行测试,需要按照以下步骤进行操作:

  1. 将两个脚本文件导入作为测试运行程序的 HTML 页面中,如清单 3 所示。

  2. 在浏览器中打开页面。

  清单 3. HTML 页面 (example1/runner.html)

1
2
3
4
5
6
7
8
9
10
11
                 
<!DOCTYPE html>
<html>
     <head>
         <meta http-equiv="Content-type" content="text/html; charset=utf-8">
         <title>Example 1</title>
         <script type="text/javascript" src="js/script.js"></script>
          <script type="text/javascript" src="js/test.js"></script>
     </head>
     <body></body>
</html>

  您可以不使用浏览器控制台,而是将结果打印在页面或由 alert()
方法生成的弹出窗口中。

  断言是测试用例中的核心元素,用来验证某一条件是否满足。例如,在 清单
2 中,addThreeToNumber (a) === valueExpected 就是一个断言。

  如果您拥有很多用例并带有很多断言,那么使用框架就会方便很多。下面的内容将会重点介绍一些最流行的
JavaScript
单元测试框架:QUnit、YUI
Test 和 JSTestDriver。

  QUnit 入门

  QUnit 是与 JUnit(Java 编程)类似的单元测试框架,jQuery 团队用它来对
jQuery 库进行单元测试。要使用 QUnit,需要按照以下方法:

  1. 下载 qunit.css 文件和 qunit.js
文件(参阅 参考资料)。

  2. 创建一个 HTML 页面,其中包含导入刚下载的 CSS 和 JavaScript
文件的特定标签。

  清单 4 显示了适用于 QUnit 的标准的 HTML 运行程序。

  清单 4. HTML 运行程序 (qunit/runner.html)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
                 
<!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/lib/qunit.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>

  假设您拥有两个函数分别负责将温度从摄氏转换为华氏,并转换回来。清单 5
显示了执行此转换的脚本。

  清单 5. 转换 (qunit/js/script.js)

1
2
3
4
5
6
7
8
9
10
                 
function convertFromCelsiusToFahrenheit(c){
    var f = c * (9/5) + 32;
    return f;
}
  
function convertFromFahrenheitToCelsius(f){
    var c = (f - 32) * (5/9);
    return c;
}

  清单 6 显示了各自的测试用例。

  清单 6. 测试用例 (qunit/js/test.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
                 
module ("Temperature conversion")
  
test("conversion to F", function(){
    var actual1 = convertFromCelsiusToFahrenheit(20);
    equal(actual1, 68, ?Value not correct?);
  
    var actual2 = convertFromCelsiusToFahrenheit(30);
    equal(actual2, 86, ?Value not correct?);
})
  
test("conversion to C", function(){
    var actual1 = convertFromFahrenheitToCelsius(68);
    equal(actual1, 20, ?Value not correct?);
  
    var actual2 = convertFromFahrenheitToCelsius(86);
    equal(actual2, 30, ?Value not correct?);
})

  QUnit 中的测试用例由 test()
方法定义。逻辑是包含在传入函数的第二个参数中。在清单 6
中,两个测试分别名为 conversion to F和 conversion to
C。每个测试包含两个断言。该测试中的断言使用了 equal() 方法。equal()
函数可以将预期值与测试函数的实际值相比较。equal()
方法中的第三个参数是错误情况下显示的消息。

  还可以通过 module() 函数将测试组织到模块中。在清单 6 中,Temperature
conversion 模块含有这两个测试。

  如果要运行测试:

  1. 在 HTML 运行程序中包含源代码和测试文件,如清单 7 所示。

  2. 在浏览器中打开页面。

  清单 7. 在运行程序中包含 script.js 和 test.js

1
2
3
4
                 
...<script type="text/javascript" src="js/script.js"></script>
<script type="text/javascript" src="js/test.js"></script>
...

  图 1 显示了 QUnit 如何在浏览器 (Firefox) 中显示结果。

  图 1. QUnit 结果

澳门新葡亰网站注册 2

  清单 6 中的断言使用了 equal() 方法,但它不是 QUnit
提供的惟一断言。QUnit 提供的其他断言包括 ok() 或 strictEqual()。清单 8
显示了正在执行的方法。

  清单 8. 更多的断言

1
2
3
4
5
6
7
8
                 
module ("Other assertion");
test("assertions", function(){
    ok(true);
    ok(3);
    strictEqual("c", "c");
    equal (3, "3");
});

  ok() 函数检查第一个参数为 true;strictEqual()
验证第一个参数严格等于第二个参数。在这些代码背后,strictEqual()
使用了=== 运算符,equal() 使用了 == 运算符。

  如果测试失败,QUnit 还提供了有用的信息。将清单 8 中的代码改成清单 9
中的代码,让上一次断言执行失败。

  清单 9. 上一次断言出现的错误

1
2
3
4
5
6
7
8
                 
module ("Other assertion");
test("assertions", function(){
    ok(true);
    ok(3);
    strictEqual("c", "c");
    strictEqual (3, "3");
});

  图 2 显示了 QUnit 执行清单 9 代码所返回的结果。

  图 2. QUnit 结果:上次测试失败

澳门新葡亰网站注册 3

  结果非常详细,而且很容易查到上次断言的预期值与实际值有什么不同。

  QUnit
另一项特性能让您在模块中的所有测试执行之前或之后执行命令。module()
函数接受 setup() 和 teardown() 回调作为第二个参数。使用 setup() 函数更新
清单 6 ,如清单 10 所示。

  清单 10. setup() (qunit/js/test-setup.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module ("Temperature conversion", {
    setup : function() {
        this.celsius1 = 20;
        this.celsius2 = 30;
  
        this.fahrenheit1 = 68;
        this.fahrenheit2 = 86;
    }
});
test("conversion to F", function(){
    var actual1 = convertFromCelsiusToFahrenheit(this.celsius1);
    equal(actual1, this.fahrenheit1);
  
    var actual2 = convertFromCelsiusToFahrenheit(this.celsius2);
    equal(actual2, this.fahrenheit2);
});
test("conversion to C", function(){
    var actual1 = convertFromFahrenheitToCelsius(this.fahrenheit1);
    equal(actual1, this.celsius1);
  
    var actual2 = convertFromFahrenheitToCelsius(this.fahrenheit2);
    equal(actual2, this.celsius2);
});

  该示例移动了设置部分的断言所使用的值,以避免在测试的逻辑中使用这些值。