如何按顺序运行Jest测试?

我通过npm test运行笑话测试。Jest默认情况下并行运行测试。是否有办法使测试按顺序运行?

我有一些测试调用依赖于更改当前工作目录的第三方代码。

153255 次浏览

CLI选项有文档记录,也可以通过运行jest --help命令来访问。

你会看到你正在寻找的选项:--runInBand

我仍在熟悉Jest,但似乎描述块是同步运行的,而测试块是异步运行的。我在一个外部描述中运行多个描述块,看起来像这样:

describe
describe
test1
test2


describe
test3

在这种情况下,test3直到test2完成才会运行,因为test3位于包含test2的描述块之后的描述块中。

这对我来说很有效,确保了模块测试的有序运行:

1)将测试保存在分开的文件中,但没有spec/test命名。

|__testsToRunSequentially.test.js
|__tests
|__testSuite1.js
|__testSuite2.js
|__index.js

2)测试套件的文件也应该是这样的(testSuite1.js):

export const testSuite1 = () => describe(/*your suite inside*/)

3)将它们导入testToRunSequentially.test.js并使用--runInBand运行:

import { testSuite1, testSuite2 } from './tests'


describe('sequentially run tests', () => {
testSuite1()
testSuite2()
})

使用串行测试运行器:

npm install jest-serial-runner --save-dev

设置jest来使用它,例如在jest.config.js中:

module.exports = {
...,
runner: 'jest-serial-runner'
};

您可以使用项目特性将其仅应用于测试的一个子集。看到https://jestjs.io/docs/en/configuration#projects-arraystring--projectconfig

https://github.com/facebook/jest/issues/6194#issuecomment-419837314复制

test.spec.js

import { signuptests } from './signup'
import { logintests } from './login'


describe('Signup', signuptests)
describe('Login', logintests)

signup.js

export const signuptests = () => {
it('Should have login elements', () => {});
it('Should Signup', () => {}});
}

login.js

export const logintests = () => {
it('Should Login', () => {}});
}

是的,您还可以以特定的顺序运行所有测试,尽管通常您的测试应该是独立的,所以我强烈警告不要依赖任何特定的顺序。说到这里,可能有一个控制测试顺序的有效案例,所以你可以这样做:

  • 添加--runInBand作为运行笑话时的选项,例如在package.json。这将按顺序而不是并行(异步)运行测试。使用--runInBand可以防止一组测试中的设置/拆除/清理等问题干扰其他测试:

  • < p > "scripts": {"test": "jest --runInBand"}

  • 将所有测试放入单独的文件夹(例如,__tests__下的单独文件夹,名为test_suites):

    __tests__

    test_suites

    test1.js

    test2.js

  • package.json中配置jest来忽略这个test_suites文件夹: "jest": { "testPathIgnorePatterns": ["/test_suites"] } < / p >
  • __tests__下创建一个新文件,例如tests.js -这是现在唯一将实际运行的测试文件。

  • tests.jsrequire中,各个测试文件按照你想要运行它们的顺序:

    require('./test_suites/test1.js');

    require('./test_suites/test2.js');

请注意——这将导致测试中的afterAll()所有测试完成后运行。从本质上讲,它破坏了测试的独立性,应该在非常有限的场景中使用。

从笑话文档:

Jest在执行之前执行测试文件中的所有描述处理程序 任何实际的测试。这是另一个建立和的原因 在*和*处理程序之前和之后拆除,而不是在 描述块。< / p >

默认情况下,一旦描述块完成 Jest运行所有的测试按顺序依次排列他们是 遇到在收集阶段,等待每一个完成和被

.

.

看看这个笑话网站给出的例子。

以防有人想在package.json选项中保留所有的笑话配置。

runInBand似乎不是一个有效的配置选项。这意味着你可以以下面的设置结束,它似乎不是100%完美的。

"scripts": {
"test": "jest  --runInBand"
},
...
"jest": {
"verbose": true,
"forceExit": true,
"preset": "ts-jest",
"testURL": "http://localhost/",
"testRegex": "\\.test\\.ts$",
...
}
...

然而,你可以像下面这样使用maxWorkers选项添加runInBand:

  "scripts": {
"test": "jest"
},
...
"jest": {
"verbose": true,
"maxWorkers": 1,
"forceExit": true,
"preset": "ts-jest",
"testURL": "http://localhost/",
"testRegex": "\\.test\\.ts$",
...
}
...

我需要它来处理端到端测试以及常规测试,而runInBand解决方案对我来说是不够的。是的:它确保在测试套件/文件中按照顺序工作,但是文件本身按照Jest为并行化选择的顺序运行,并且不容易控制。如果您需要测试套件本身的稳定顺序,那么您可以这样做。

所以除了--runInBand,我做了下面的事情。顺便说一下,我在一个存储库中使用了单独的项目。

  1. 我的jest.config.js看起来像这样:

     module.exports = {
    testSequencer: "./__e2e__/jest/customSequencer.js",
    projects: [{
    "rootDir": "<rootDir>/__e2e__",
    "displayName": "end-to-end",
    ...
    
    这里,我显式地将displayName添加为end-to-end 我稍后再用。你想做多少就做多少,跟往常一样,但是 我有两个,一个用于正常的单元测试,一个用于端到端测试

    注意testSequencer字段必须是全局的. c。如果你附上它 对于一个项目,它将被验证,但随后将被默默地忽略。这是一个 开玩笑的决定,使排序更好地运行多个项目

  2. testSequencer字段指向包含此字段的文件。这个进口 测试排序器的默认版本,然后对测试进行分区 分为两组,一组用于end-to-end项目中的测试,而所有的 休息。其余的都委托给继承的排序器,但在 端到端的集合按字母顺序排序,然后连接

     const Sequencer = require('@jest/test-sequencer').default;
    
    
    const isEndToEnd = (test) => {
    const contextConfig = test.context.config;
    return contextConfig.displayName.name === 'end-to-end';
    };
    
    
    class CustomSequencer extends Sequencer {
    sort(tests) {
    const copyTests = Array.from(tests);
    const normalTests = copyTests.filter((t) => ! isEndToEnd(t));
    const endToEndTests = copyTests.filter((t) => isEndToEnd(t));
    return super.sort(normalTests).concat(endToEndTests.sort((a, b) => (a.path > b.path ? 1 : -1)));
    }
    }
    
    
    module.exports = CustomSequencer;
    

这个组合像Jest喜欢的那样运行所有常规测试,但总是以alpha顺序运行端到端测试,为用户模型提供他们需要的顺序的端到端测试额外的稳定性。

如果你是Jest的新手,正在寻找一个完整的,循序渐进的例子,如何让一个特定的测试文件总是在第一个或最后一个运行,下面是:

  1. 创建一个名为“testsequcer .js"在任何你喜欢的道路上。
  2. 将下面的代码粘贴到该文件中。
const TestSequencer = require('@jest/test-sequencer').default;
const path = require('path');


class CustomSequencer extends TestSequencer {
sort(tests) {
const target_test_path = path.join(__dirname, 'target.test.js');


const target_test_index = tests.findIndex(t => t.path === target_test_path);


if (auth_test_index == -1) {
return tests;
}


const target_test = tests[target_test_index];


const ordered_tests = tests;


ordered_tests.splice(target_test_index, 1);
ordered_tests.push(target_test); // adds to the tail
// ordered_tests.unshift(target_test); // adds to the head


return ordered_tests;
}
}


module.exports = CustomSequencer;
  1. 设置“maxWorkers"选项为“true”;在你的包裹里。Json笑话配置。同时,set "testSequencer"选项作为您新创建的&;testSequencer.js"文件的路径。
{
"name": "myApp",
"version": "1.0.0",
"main": "app.js",
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js",
"test": "jest"
},
"author": "Company",
"license": "MIT",
"dependencies": {
...
},
"devDependencies": {
"jest": "^27.5.1",
...
},
"jest": {
"testSequencer": "./testSequencer.js",
"maxWorkers": 1
}
}
  1. 运行npm test并观察每个测试文件将在每个测试完成后逐个运行。你牺牲了一些时间,但你这样做保证了订单。

额外的好处:你还可以按字母顺序、文件夹名等顺序排列测试文件。只需修改“testSequencer.js"文件到您的偏好,并返回一个与"test "格式相同的数组;数组,它是主“sort”的参数;发挥作用,你就会好起来。

Jest按照在收集阶段遇到的顺序连续运行所有测试

你可以利用它创建特殊的测试文件alltests.ordered-test.js:

import './first-test'
import './second-test'
// etc.

并添加一个带有testMatch的jest配置,它将使用该文件名运行测试。

这将按该顺序加载每个文件,从而以相同的顺序执行它们。