网络埋伏纪事

如何用Mocha测试JavaScript - 基础知识

网络埋伏纪事 · 2017-06-15翻译 · 1107阅读 原文链接

Mocha是最受欢迎的Node.js测试框架之一,它看起来很令人生畏,实际上却很容易入门。

这个教程要讲什么?

本教程是关于Mocha基础知识。在本教程结束之前,我们将成功地使用Mocha编写第一个测试。我们会了解如何设置Mocha,如何分组测试以及如何使用断言库。明天我将发布第2部分,其重点是更高级的测试技术,以及将测试与实际的代码整合在一起! _编辑按:第2部分已经发布了,可以在这里找到。


Mocha的文档还不错。不过,对于JavaScript新手来说,这文档有点厚,不太好理解。我会带大家玩一遍来自于Mocha文档中的第一个例子。对于有些概念,我会比文档做更多的分析和分解,以确保大家准确理解发生了什么。

准备好了么?我们开始吧!

全局安装Mocha

通过执行如下命令,全局安装Mocha:

$ npm install -g mocha

当全局安装npm模块时,不仅仅是将其用于当前项目,而是能像命令行工具一下访问和使用该模块。一旦Mocha被全局安装了,我们就能够在命令行上使用mocha关键字执行命令。

创建一个项目

接下来,我们将创建一个名为test的项目目录。在test文件夹中,我们将创建一个名为test.js的文件。最后,我们通过执行npm init初始化我们的项目。

如果你不熟悉的话,npm init是一个以交互方式创建package.json文件的简单方法。只需回答问题,然后敲回车键即可。这里最重要的问题是 'test command:' - 回答'mocha'即可。这样我们只需键入npm test就可以运行mocha。

完成后,应该有一个看起来像如下这样的文件结构:

test
|-- test.js
|-- package.json

这里package.json文件也应该包含如下的json:

"scripts": {
  "test": "mocha"
},

有了上面这些东西后,我们就做好了测试的准备了!

编写第一个测试

我们打算直接从Mocha文档中复制一个测试,然后我会带大家看看到底发生了什么。将如下代码复制到test.js文件中:

var assert = require('assert');
describe('Array', function() {
  describe('#indexOf()', function() {
    it('当值不存在时,应该返回 -1 ', function(){
      assert.equal(-1, [1,2,3].indexOf(4));
    });
  });
});

现在在命令行中用npm test运行测试,应该得到如下输出结果:

Array
  #indexOf()
    ✓ 当值不存在时,应该返回 -1

1 passing (9ms)

我们的测试通过!太棒了。不过我们不知道为什么...且听下面分解。


记住,Mocha是一个测试框架。就是说它用于组合和执行测试。在编写测试时,应该注意两个基本的函数调用:**describe()****it()**。两个都在上面的示例中用到了。

  • describe()只不过是Mocha中将测试分组的一种方法。我们可以按必要的深度来将测试分组嵌套。describe()带有两个参数,第一个是测试组的名称,第二个是回调函数。
    describe('string name', function(){
      // 这里可以嵌套更多的 describe(),或者写测试
    });

回想一下早前的例子。我们有一个名为Array的测试组,里面有一个名为#indexOf()的测试组,最后最里面我们的实际测试。

  • it()用于单个测试用例。it()应该被写成好像你大声说出来:“它应该等于零”、“它应该记录用户”,等等。it()有两个参数,一个参数是一个字符串,说明测试应该做什么,第二个参数是一个包含实际测试的回调函数:
    it('should blah blah blah', function(){
      //测试用例放在这里
    });

我们可以在测试框架(Mocha)中使用断言库。断言库是验证事物正确的工具 - 是它来实际验证测试结果。

请注意,并非一定要用断言库,不过用断言库会使测试更容易点。Mocha允许我们使用想用的任何断言库。在上面的例子中(以及所有其他示例),我们用的是Node.js内置的assert模块。因此,我们用这行代码导入assert模块:

var assert = require('assert');

assert中包含很多不同的断言测试。我们已经使用的一个是assert.equal(actual, expected);,它用双等号(==)测试实际参数和期待的参数之间的相等性。

最后一次回忆一下我们的原例:

it('当值不存在时,应该返回 -1', function(){
  assert.equal(-1, [1,2,3].indexOf(4));
});

这里我们所做的就是测试[1,2,3].indexof(4)是否等于-1。如果预期参数等于实际参数,则测试通过。否则,测试失败。

再到命令行,用npm test运行我们的测试:

Array
  _#indexOf()_
    ✓ 当值不存在时,应该返回 -1

1 passing (9ms)

结果一行一行分解就是:

  1. 第一个测试组Array

  2. 嵌套的测试组indexOf()

  3. 表示通过测试的检测标记,以及测试描述

  4. 一个摘要,表明我们有1次通过测试,测试花了9毫秒

放在一起

现在我们已经有了所有的东西,所以可以把它放在一起了。这是我们的原始测试,用注释解释了每一行:

// Require 内置的 'assertion' 库
var assert = require('assert');
// 创建一组关于数组的测试
describe('Array', function() {
  // 在 Array 组内,为 indexOf 创建一组测试
  describe('#indexOf()', function() {
    // 一个字符串解释我们在测试什么
    it('当值不存在时,应该返回 -1', function(){
      // 实际测试: -1 应该等于 indexOf(...)
      assert.equal(-1, [1,2,3].indexOf(4));
    });
  });
});

检验学习情况

好了,该检验一下学习情况了。不要滚动查看答案,请编写如下测试:

  1. 创建一个名为Math的测试组

  2. 在Math组内创建两个测试

  3. 第一个测试:应该测试是否3*3=9

  4. 第二个测试:应该测试是否(3-4)*8 = -8


不要向下滚动,直到让两个测试通过!

不要向下滚动,直到让两个测试通过!

不要向下滚动,直到让两个测试通过!

不要向下滚动,直到让两个测试通过!


测试答案

大家能做到吗?如果没有,没关系!如果做到了,干的不错!下面我们看看注释好的解决方案:

// require 内置的 'assertion' 库
var assert = require('assert');
// 创建一个名为Math的测试套件(组)
describe('Math', function() {
    // 第一个测试:一个字符串解释我们在测试什么
    it('should test if 3*3 = 9', function(){
      // 实际测试: 3*3 应该等于 9
      assert.equal(9, 3*3);
    });
    // 第二个测试: 一个字符串解释我们在测试什么
    it('should test if (3-4)*8 = -8', function(){
      // 实际测试: (3-4)*8 应该等于 -8
      assert.equal(-8, (3-4)*8);
    });
});

并且当执行npm test时:

Math
  √ should test if 3*3 = 9
  √ should test if (3-4)*8 = -8

2 passing (13ms)

你做到了。

干的不错!现在(理想情况下)我们可以理解Mocha是什么,如何设置它,如何分组测试以及如何使用断言库。不过,如果无法实际测试代码,那么测试有什么好处呢?在明天的文章中,我们将测试集成到现有的JavaScript文件中! _编辑按:第2部分已经推出。请查看这里

相关文章