Nodejs实战 —— 测试 Node 程序 (2)

单元测试是指通过编写代码来测试程序中的各个部分。编写测试代码会让你更认真思考程序的设计选择,尽早避开各种陷阱。测试还会让你确信自己最近的修改没有引入错误。尽管单元测试需要在编码时做些工作,但以后每次修改程序后都不用自己手动测试了,所以还是能节省很多时间的。

做单元测试需要些技巧,而异步逻辑有带来了新的挑战。因为异步单元测试可以并行运行,所以必须小心,确保测试不会互相干扰。比如说,如果测试在硬盘上创建了一个临时文件,那么在完成测试后删除文件时一定要谨慎,以免删除另外一个未完成的测试正在使用过的文件。因此很多单元测试框架都有流程控制,可以让测试按顺序运行。

本节介绍的内容:

Node 自带的 assert 模块 —— TDD 风格自动化测试的工具

Mocha —— 相对比较新的测试框架,可以用来做 TDD- 或 BDD-风格的测试

Vows —— 得到广泛应用的 BDD 风格测试框架

Should.js —— 构建在 Node assert 模块之上的模块,提供 BDD 风格的断言

assert 模块

assert 模块是 Node 中大多数单元测试的基础,它可以测试一个条件,如果条件未满足,则抛出错误。很多第三方测试框架都用到了 assert 模块,甚至没有测试框架也可以用它做测试。

简单的例子:

假设有一个简单的待办事项程序,它把事项存在内存里,而你要断言它做的是你认为它做的。

下面的代码定义的模块实现了程序的核心功能,包括待办事项的创建、获取和删除。它还包括一个简单的 doAsync 方法,所以还可以看到如何测试异步方法。

// todo.js class Todo { constructor() { // 定义待办项数据库 this.todos = []; } add(item) { if (!item) throw new Error('Todo.prototype.add requires an item'); this.todos.push(item); } deleteAll() { this.todos = []; } get length() { return this.todos.length; } // 两秒后带着 true 调用回调 doAsync(cb) { setTimeout(cb, 2000, true); } } module.exports = Todo;

接下里用 assert 模块测试这段代码,下面的代码加载了必需模块,创建了新的待办事项列表,还声明一个变量记录完成的测试数量。

// test.js const assert = require('assert'); const Todo = require('./todo'); const todo = new Todo(); let testsCompleted = 0;

用 equal 检查变量的值,测试待办事项程序的删除功能

// test.js function deleteTest() { // 添加数据来删除 todo.add('Delete Me'); // 断言数据添加成功 assert.equal(todo.length, 1, '1 item should exist'); todo.deleteAll(); assert.equal(todo.length, 0, 'No items should exist'); // 记录测试已完成 testsCompleted++; }

上面的测试添加一个待办事项,然后再删除,所以最后应该没有待办事项。如果程序能正常工作,那么 todo.length 的值应该是 0。如果程序出现问题,则会有异常抛出。如果 todo.length 不是 0.那么这个断言会在栈跟踪中显示一条错误消息,在控制台中输出 ‘No items should exist“,在断言后面将 testCompleted 加一,记录已完成了一次测试。

用 notEqual 找出逻辑中的问题

function addTest() { todo.deleteAll(); todo.add('Added'); // 断言有事项存在 assert.notEqual(todo.length, 0, '1 item should exist'); testsCompleted++; }

assest 模块中还有一个 notEqual 断言,当程序产生特定的值表明逻辑有问题时,可以采用这种断言。上面展示了在删除所有待办事项又添加了一个事项,然后再获取所有事项,如果事项的数量为0,断言就会失败并抛出异常。

其他功能:strictEqual、notStrictEqual、deelEqual、notDeepEqual

除了 equal 和 notEqual ,assert 模块还提供了更严格的版本,strictEqual 和 notStrictEqual,它们在进行判断时用的是严格的相等操作符 ===。

assert 模块也有用来比较对象的 deepEqual 和 notEqual ,这些断言中的 deep 表明它们会层层深入对两个对象进行比较,比较两个对象的属性,如果属性也是对象,则会继续比较属性的属性。

用 ok 测试异步值是否为 true

因为是异步测试,所以要提供一个回调函数(cb),向测试运行者发送测试结束的信号——不能像同步测试那样靠返回语句来表明测试结束了。要判断 doAsync 的结果值是否为 true,可以用 ok 断言,用它判断一个值是否为 true 很容易。

function doAsyncTest(cb) { todo.doAsync(value => { // 断言值为 true assert.ok(value, 'Callback should be passed true'); testsCompleted++; cb(); }); }

测试能否正确抛出错误

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwxjzz.html