成组运行 Jest 测试套件

Posted

技术标签:

【中文标题】成组运行 Jest 测试套件【英文标题】:Run Jest test suites in groups 【发布时间】:2018-10-14 18:21:01 【问题描述】:

我正在通过 Jest 和 supertest 为新 API 编写大量测试。在运行测试之前,我正在设置一个测试数据库并在其中填充用户:

测试命令

jest --forceExit --config src/utils/testing/jest.config.js

文件 jest.config.js

module.exports = 
  rootDir: process.cwd(),

  // Sets up testing database with users
  globalSetup: './src/utils/testing/jest.setup.js',

  // Ensures connection to database for all test suites
  setupTestFrameworkScriptFile: './src/utils/testing/jest.db.js',


所以我从一些用户的数据库开始进行测试。问题是这样的:

我的一些测试依赖于其他测试的成功。在这个应用程序中,用户可以上传图像,并将它们分组。所以我的分组端点套件取决于我的图像上传套件的成功,等等。

我很清楚很多人可能会说这是不好的做法,并且测试不应该依赖于其他测试。话虽如此,我真的宁愿通过supertest 保留我的所有测试,而不是依赖注入等。我不想必须精心设置测试条件(例如,人为地创建一堆用户图像在运行测试之前),因为:(1)这只是逻辑的重复,(2)它增加了某些东西的可能性。

有没有办法将笑话套件分组?例如,按顺序运行套件:

jest run creationSuite
jest run modificationSuite

这样,我的所有“creationSuite”测试都可以同时运行,all 的成功将触发“modificationSuite”以快速失败的方式运行,等等。 p>

另外,在测试套件内部指定对其他测试套件的依赖会很棒:

describe('Grouping endpoint', () => 
    // Somehow define dependencies
    this.dependsOn(uploadSuite)

【问题讨论】:

【参考方案1】:

您可以使用jest-runner-groups 来分组定义和运行测试。安装并添加到 Jest 配置后,您可以使用 docblock 表示法标记您的测试,如下所示:

/**
 * Foo tests
 *
 * @group group1/subgroup1
 * @group unit/foo
 */

describe( 'Foo class', () => 
    ...
 );
/**
 * Bar tests
 *
 * @group group1/subgroup2
 * @group unit/bar
 */

describe( 'Bar class', () => 
    ...
 );

更新您的 jest 配置以指定新的跑步者:

// jest.config.js
module.exports = 
    ...
    runner: "groups"
;

然后要运行特定的组,需要使用--group= 参数:

// Using the Jest executable
jest --group=mygroup

// Or npm
npm test -- --group=mygroup

您还可以使用多个--group 参数来运行多个组:

// Will execute tests in the unit/bar and unit/foo groups
npm test -- --group=unit/bar --group=unit/foo

// Will execute tests in the unit group (including unit/bar and unit/foo groups)
npm test -- --group=unit

【讨论】:

该包不适用于 jest-expo 预设:/【参考方案2】:

我用--testNamePattern 标志完成了它。这是程序。

假设您有两组测试:

DevTest 用于开发环境测试 ProdTest 用于在生产环境中进行测试

如果您只想测试开发环境所需的那些功能,您必须在测试说明中添加DevTest

describe('(DevTest): Test in development environment', () => 
  // Your test
)

describe('(ProdTest): Test in production environment', () => 
  // Your test
)

describe('Test everywhere', () => 
  // Your test
)

之后,您可以将命令添加到您的package.json 文件中:

  "scripts": 
    "test": "jest",
    "test:prod": "jest --testNamePattern=ProdTest",
    "test:dev": "jest --testNamePattern=DevTest",
    "test:update": "jest --updateSnapshot"
  

命令npm test 将运行所有您的测试,因为您没有使用标志--testNamePattern。如果您想运行其他测试,只需使用 npm run test:dev 即可。

但在命名测试组时要小心。它们在测试描述中使用正则表达式进行搜索,您不希望此命令匹配其他单词。

【讨论】:

【参考方案3】:

Jest 测试套件在多个线程中执行,这是它的主要优点之一。以这种方式可以更快地完成测试运行,但测试序列并非按设计保留。

可以使用runInBand 选项禁用此功能。

可以使用 testNamePattern 选项根据名称选择测试和套件,或者使用 testPathPattern option 根据路径选择测试和套件。

由于一个套件依赖于另一个套件,因此它们可能会按照预期运行的顺序组合成一个套件。它们仍然可以驻留在不同的文件中(确保它们不被 Jest 匹配),例如:

// foobar.test.js
describe(..., () => 
  require('foo.partial-test.js');
  require('bar.partial-test.js');
);

问题是这样的:

我的一些测试依赖于其他测试的成功。

这是真正的问题。依赖先前测试状态的方法在任何类型的自动化测试中都被认为是有缺陷的。

我不想精心设置测试条件(例如,在运行测试之前人为地创建一堆用户图像),因为:(1)这只是逻辑的重复,以及(2)它增加破坏的可能性。

无需人为设置测试条件(夹具)。可以从现有环境中提取夹具,如果您确定它们的质量,甚至可以从当前测试的结果中提取。

冗余和重言式自然发生在自动化测试中,它们没有任何问题。通过正确管理夹具和共享代码,可以使测试变得 DRYer。

恰恰相反,错误总是累积的。创建错误先决条件的测试可能会通过,但另一个测试会失败,从而产生调试难题。

【讨论】:

“无需人为地设置测试条件(夹具)。夹具可以从现有环境中提取,如果您确定其质量,甚至可以从当前测试的结果中提取。” - 你能多说点吗? 例如如果您的案例是数据库测试并且您需要非空数据库,您可以从数据库中获取一些满足测试用例的现有记录,将它们保存到 .sql 夹具并在 beforeEach 中恢复。由于您的案例是 API 测试,您可能需要将真实的 API 响应转储到文件并使用 Nock 模拟 HTTP。 正是我的观点。每次 API 发生“足迹”更改时,都需要更新这些模拟文件。这就是我想避免的。 这通常是正确的做法,尽管它很麻烦。通过这种方式,测试变得可预测。无论如何,答案的第一部分解决了问题本身,这些都是可能的方式。我会选择套件和 .partial-test.js 的层次结构,因为多线程是有价值的 Jest 功能,不应该白白丢弃。 抱歉,partial-test.js 是什么?

以上是关于成组运行 Jest 测试套件的主要内容,如果未能解决你的问题,请参考以下文章

JEST 测试套件无法运行:TypeError: (0 , _reactRedux.connect) 不是函数

如何配置 playwright-jest 以排除测试套件(规范)文件以进行运行?

测试套件无法运行在 vue3 中使用 jest 时找不到模块'vue-template-compiler

有没有办法用 Jest 顺序运行一些测试?

测试套件无法运行

Jest - 在一个测试套件中多次测试模块