Node.js测试模块介绍

前段时间,我偶然发现了Node.js测试模块。在最近几年尝试了各种JavaScript测试工具后,我决定抽出一些时间来测试它并了解其工作原理。

在继续阅读之前,请注意在撰写本文时(2023年4月),该模块仍处于实验性阶段,可能会在未来的版本中发生变化。虽然不建议在生产环境中使用,但仍值得学习,因为它可能在以后派上用场。

那么,Node.js测试模块与Jest和Vitest等工具相比如何呢?正如预期的那样,它的功能比其他工具少,这是可以理解的,因为它仍处于早期阶段。然而,核心功能已经存在,并且非常容易使用和设置,因为它不需要第三方依赖

在使用该模块之前,您需要导入它。您很可能还需要导入断言模块。以下是导入两者的方法:

import test from 'node:test';
import assert from 'node:assert/strict';

此外,如果您想要使用测试模块的describeit等方法,您还需要导入它们。例如:

import { describe, it } from 'node:test';

现在您已经导入了该模块,可以开始编写测试了。测试模块提供了一个最简单形式的test函数,它接受两个参数:

  • name:描述测试的字符串
  • fn:包含测试逻辑的函数

让我们来看一个例子:

import test from 'node:test';
import assert from 'node:assert/strict';

test('我的测试', () => {
  assert.strictEqual(1, 1);
});

这很简单,但是如何从命令行运行测试呢?与大多数其他工具不同,您不需要在package.jsonscripts对象下创建一个新的条目。相反,您可以直接运行node --test命令:

node --test

运行此命令将匹配某些文件模式,例如以.test.js结尾的文件和位于test目录下的文件。您可以在文档中了解更多信息。此外,您还可以手动指定一个或多个以空格分隔的文件模式来运行测试:

node --test my-example.test.js

这些基本指令可能涵盖了一些简单的测试,但是没有更高级的功能,测试工具是不完整的。两个重要的测试基本功能是设置和拆卸函数。测试模块提供了beforeEachafterEach函数,分别在每个测试之前和之后运行。

请注意,您可以导入这些函数并使用它们,但也有另一种方法。通过将测试函数异步化并将参数传递给测试函数,您可以将beforeEachafterEach函数作为测试对象的方法使用。我发现这种方法更方便一些,所以下面的示例中我将使用这种方法。下面是示例代码:

import test from 'node:test';
import assert from 'node:assert/strict';

```js
test('my test', async t => {
  let a;

  t.beforeEach(() => {
    a = 1;
  });

  t.afterEach(() => {
    a = 0;
  });

  await t.test('my subtest', () => {
    assert.strictEqual(a, 1);
  });
});

虽然这听起来很好,但你可能想知道一个真实世界的例子是什么样子的。我编写了一个小函数,它会改变一个数字数组并返回一个值,以便进行演示。逻辑并不特别复杂或有趣,但足以让模块运行起来。让我们来看一下:

import test, { describe } from 'node:test';
import assert from 'node:assert/strict';

const doubleAndSum = (arr, mod = 0) => {
  let sum = 0;
  Object.entries(arr).forEach(([i, v]) => {
    if (v % 2 === mod) arr[i] = v * 2;
    else sum += v;
  });
  return sum;
};

describe('doubleAndSum', () => {
  let arr, sum;

  test('when mod is 0', async t => {
    t.beforeEach(() => {
      arr = [1, 2, 3];
      sum = doubleAndSum(arr, 0);
    });

    await t.test('sums the even values', () => {
      assert.equal(sum, 4);
    });

await t.test('将偶数值加倍', () => {
      assert.equal(arr[1], 4);
    });
  });

  test('当模数为1时', async t => {
    t.beforeEach(() => {
      arr = [1, 2, 3];
      sum = doubleAndSum(arr, 1);
    });

    await t.test('将偶数值求和', () => {
      assert.equal(sum, 2);
    });

    await t.test('将奇数值加倍', () => {
      assert.equal(arr[0], 2);
      assert.equal(arr[2], 6);
    });
  });
});

至此为止!希望到现在你对Node.js测试模块有了一个很好的了解。如果你想深入了解,还有很多内容,比如覆盖率报告、监视模式模拟等等。你可以在文档中找到更多信息。