使用 DOH 对 Web 前端 JavaScript 进行单元测试 -2
- UID
- 1066743
|
使用 DOH 对 Web 前端 JavaScript 进行单元测试 -2
使用 DOH 编写第一个测试用例:Hello World!接下来,我们来编写第一个测试用例,最好的方式自然是采用 Hello, World。刚才在建立测试框架的时候,我们已经建立了相应的目录结构。为了方便,我们在 package 目录下新建 SayHello.js,其代码如清单 2 所示:
清单 2. SayHello测试用例1
2
3
4
5
6
7
| dojo.provide("package.SayHello");
doh.register("package.SayHello",[
function isSayHelloToWorld(){
doh.assertEqual("Hello, World","Hello, China");
}
]);
|
对于上述清单,我们主要关注 2 个要点:doh.register 用来注册函数测试用例;doh.assertEqual 是断言,用来比较 Hello, World 和 Hello, China 的值是否相等。
编写完测试用例后,就需要将该测试用例添加到 testModule 里去了,在这里是 <YOUR_DIR>/package/module.js,其代码如清单 3 所示:
清单 3. 在module.js中添加SayHello测试用例1
2
3
4
5
6
7
| dojo.provide("package.module");
try{
dojo.require("package.SayHello");
}catch(e){
doh.debug(e);
}
|
在完成上述步骤之后,请在浏览器中打开 runner.html 页面,如图 2 所示:
图 2. 测试用例 SayHello 的运行结果对于上图,红色意味着 SayHello 测试用例 Failed,这是因为 Hello, World 和 Hello, China 是不相等的。另外,我们不难发现,测试结果页面主要包括了三个区域:测试套件列表,进度条,Log 视图。
虽然我们已经完成了第一测试用例,但 DOH 提供了丰富的功能,所以下文我们主要针对注册函数,断言和异步测试进行详尽的讲述。
如何注册函数测试用例?DOH 提供了大量的注册函数来注册函数测试用例。为了方便介绍,我根据参数和测试用例编写的方式将注册函数划分为三类。
首先,我们来看第一类,它的函数原型为:doh.regFunName(group, testCase)。原型中的标识如表 1 所示:
表 1. doh.regFunName(group, testCase)函数原型中的标识描述可选的值 regFunName 函数名 registerTestNs
registerGroup
registerTest
registerTests
register Group 测试用例的名字 String testCase 测试主体 Namespace Object
Function
Fixture
Array of Function
Array of Fixture
对于这个表可能有些迷惑,regFunName 有 5 种,而 testCase 有 5 种,也就是组合就有 25 种。下面我将给出它们之间组合的关系,如图 3 所示:
图 3. regFunName 与 testCase 之间组合的关系在上图中,我们提到了 Ns(Namespace) Object 和 Fixture,下面我们将给出简单的解释:
Ns Object,形如代码清单 4 所示。以“_”开头的函数被 DOH 认为是私有函数,DOH 运行测试用例时并不 Run 这些私有函数。
清单 4. Ns Object示例1
2
3
4
5
6
7
8
9
10
| {
_privateFun: function(){
doh.t(false);
},
publicFunOne: function(){
console.info("publicFunOne");
doh.t(true);
}
}
|
Fixture Object,形如代码清单 5 所示。其中,name 为测试用例的名字;timeout 为该测试用例运行的超时时间,若超时将抛出超时异常;setUp 在 runTest 之前运行,用于准备 runTest 之前的环境;runTest 为测试用例的核心函数,一般在这里进行测试;tearDown 在 runTest 之后运行,用于释放资源等。
清单 5. Fixture Object示例1
2
3
4
5
6
7
8
9
10
11
12
13
| {
name: “testCaseName”,
timeout: 5000,
runTest: function(){
// …
},
setUp: function(){
// …
},
tearDown: function(){
// …
}
}
|
接下来是第二类,它的函数原型为:doh.registerGroup(group, testCase, setUp, tearDown)。该函数原型中的参数同第一类基本一致。不同的是,setUp 在 testCase 之前运行,tearDown 在 testCase 之后运行。若 testCase 为 Fixture Object,那么它的运行顺序为:setUp->(setUp->runTest->tearDown)->tearDown。
最后是第三类,它的函数原型为:doh.registerDocTests(module)。该注册函数是 DOH 比较特殊,也是比较有趣的一个。下面给出一个简单的示例,代码如清单 6 所示:
清单 6. doh.registerDocTests(module)示例1
2
3
4
5
6
7
8
| function funOne(){
// >>> var val1 = "a"
// >>> var val2 = "b"
// >>> val1 + val2
// "ab"
// need empty line console.info("I am funOne!");
}
|
在这里有几个关键点需要注意:注释中必须以 >>> 作为开头;期望的值不能以 >>> 开头,并且与上一行之间要以回车分隔;在测试片段之后需要添加一个空行。
如何书写断言?DOH 作为 Javascript 对 JUnit 的回应,DOH 也提供了大量的断言,主要包括 5 种:
- doh.assertTrue(/*Object*/ condition),对 condition 求值,看它是否“真”。可以简写为:doh.t。
- doh.assertFalse(/*Object*/ condition),对 condition 求值,看它是否为“假”。可以简写为:doh.f。
- doh.assertEqual(/*Object*/ expected, /*Object*/ actual),比较 expected 的值与 actual 的值是否相等。可简写为:doh.is。
- doh.assertNotEqual(/*Object*/ notExpected, /*Object*/ actual),比较 notExpected 的值与 actual 的值是否不相等。
- doh.assertError(/*Error object*/expectedError, /*Object*/scope, /*String*/functionName, /*Array*/args),用来判断在 scope 上下文情况下,函数名为 funtionName,参数列表为 args 的函数抛出的异常是否为 expectedError。可简写为:doh.e。对于此种断言可能不是很好理解,下面给出示例代码清单 7:
清单 7. doh.assertError示例代码1
2
3
4
5
6
7
8
| function MyError(){};
var scrope = {};
scrope.throwError = function(){
throw new MyError();
}
doh.assertError(MyError, scrope, "throwError", []);
|
|
|
|
|
|
|