[TOC]

原文链接:https://javascript.info/testing-mocha,translate with ❤️ by zhangbao.

自动化测试将用于进一步的任务。

它实际上是开发人员“教育最低限度”的一部分。

为什么我们需要测试?

当我们编写一个函数时,我们通常可以想象它应该做什么:哪些参数给出了哪些结果。

在开发过程中,我们可以通过运行它并将结果与预期结果进行比较来检查功能。 例如,我们可以在控制台中执行此操作。

如果出现问题 - 那么我们修复代码,再次运行,检查结果 - 依此类推,直到它工作为止。

但这种手动“重新运行”并不完美。

当通过手动重新运行测试代码时,很容易忽略某些东西。

例如,我们正在创建一个函数f。 写了一些代码,测试:f(1)有效,但f(2)不起作用。 我们修复代码,现在f(2)工作。 看起来完整? 但我们忘了重新测试f(1)。 这可能会导致错误。

这很典型。 当我们开发某些东西时,我们会考虑很多可能的用例。但是很难期望程序员在每次更改后手动检查所有这些程序员。 因此,修复一件事并打破另一件事变得容易。

自动化测试意味着除了代码之外,测试还是单独编写的。 它们可以轻松执行并检查所有主要用例。

行为驱动型开发(BBD)

让我们使用一种名为行为驱动开发的技术,简称BDD。 许多项目都使用这种方法。 BDD 不只是测试,那更多。

BDD 是三件事:测试和文档和示例。

够了。我们来看看这个例子。

开发“pow”:规范

我们现在需要写一个函数 pow(x, n) 是求 x 的 n 次幂。我们认为 n>=0。

这个任务只是一个例子:JavaScript 中的 ** 运算符可以做到这一点,但在这里我们专注于可以应用于更复杂任务的开发流程。

在开始写 pow 函数代码之前,我们先想一下函数能干嘛以及怎么去描述它。

这种描述称为s pecification,或简称为 spec,如下所示:

describe("pow", function() {

  it("raises to n-th power", function() {
    assert.equal(pow(2, 3), 8);
  });

});

一个规范有三个主要的构建模块,您可以在上面看到:

describe("title", function() { ... })

我们正在描述什么功能。用于组合“workers” - 也就是 it 块。在我们的例子中,我们描述了函数 pow。

it("title", function() { ... })

在 it 的 title 中,我们以人类可读的方式描述特定用例,第二个参数是测试它的函数。

assert.equal(value1, value2)

it 块里的代码,如果实现是正确的话,就会不出错的执行。

函数 assert.* 用来检查是否函数 pow 按照预期执行了。我们这里使用到了其中之一的方法——assert.equal,它会比较参数并在它们不相等时产生错误。这里,它检查 pow(2, 3) 的结果是否等于 8。

还有其他类型的比较和检查我们会进一步看到。

开发流

开发流通常是这样的:

  1. 编写初始规范,测试最基本的功能。

  2. 创建初始实现。

  3. 为了检查它是否有效,我们运行了运行规范的测试框架 Mocha(很快就会有更多细节)。显示错误。 我们会做出更正,直到一切正常。

  4. 现在我们有一个带有测试的可以运行的初始实现。

  5. 我们在规范中添加了更多用例,实现可能尚未支持。测试开始失败。

  6. 进入第三步,更新咱们的实现直到没有错误发生。

  7. 重复第 3~6 步直到功能完全实现了。

因此,开发是迭代的。我们编写规范,实现它,确保测试通过,然后编写更多测试,确保它们工作等。最后,我们有一个工作实现和测试。

在我们的例子中,第一步是完成的:我们有一个 pow 的初始规格。所以让我们来实现。但在此之前让我们对规范进行“零”运行,只是为了看到测试正在运行(它们都会失败)。

行动规范

在本教程中,我们将使用以下 JavaScript 库进行测试:

  • Mocha:核心框架:它提供常见的测试功能,包括 describe 和 it 以及运行测试的主要功能。

  • Chai:提供很多不同的断言,它允许使用许多不同的断言,现在我们只需要 assert.equal。

  • Sino:一个监视函数的库,模拟内置函数等等,我们以后需要它。

这些库适用于浏览器内和服务器端测试。在这里,我们将考虑浏览器变体。

包含这些框架和 pow 规范的完整 HTML 页面:

<!DOCTYPE html>
<html>
<head>
  <!-- add mocha css, to show results -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.css">
  <!-- add mocha framework code -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.js"></script>
  <script>
    mocha.setup('bdd'); // minimal setup
  </script>
  <!-- add chai -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.js"></script>
  <script>
    // chai has a lot of stuff, let's make assert global
    let assert = chai.assert;
  </script>
</head>

<body>

  <script>
    function pow(x, n) {
      /* function code is to be written, empty now */
    }
  </script>

  <!-- the script with tests (describe, it...) -->
  <script src="test.js"></script>

  <!-- the element with id="mocha" will contain test results -->
  <div id="mocha"></div>

  <!-- run tests! -->
  <script>
    mocha.run();
  </script>
</body>

</html>

页面可以分成四个部分:

  1. :未测试添加第三方库和样式。

  2. 携带被测试函数的