如何顺序运行Jest测试?

时间:2015-09-24 00:50:05

标签: jestjs

我正在通过npm test运行Jest测试。 Jest默认并行运行测试。有没有办法让测试顺序进行?

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

10 个答案:

答案 0 :(得分:139)

未记录CLI选项,但可以通过运行命令jest --help来访问它。

然后,您会看到您要查找的选项:--runInBand

答案 1 :(得分:6)

我仍然对Jest熟悉,但是看来描述块是同步运行的,而测试块是异步运行的。我正在外部描述中运行多个描述块,如下所示:

describe
    describe
        test1
        test2

    describe
        test3

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

答案 2 :(得分:3)

使用串行测试运行器:

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

设置玩笑以使用它,例如在jest.config.js中:

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

您可以使用项目功能仅将其用于部分测试。

答案 3 :(得分:3)

虽然 --runInBand 可以工作,但它的作用比您需要的要多一些 - 根据 Jest 的文档:

<块引用>

在当前进程中连续运行所有测试,而不是创建运行测试的子进程的工作池 (...)

通常,Jest 使用一个父调度程序进程运行,该进程将子进程调度为并行有效运行测试的工作线程。 runInBand 似乎通过将所有内容压缩到一个进程中来打破该架构。

为了保留核心范式并按顺序运行,您可以使用 --maxWorkers 1,这会将并发运行的工作程序数量限制为 1(从而导致顺序运行):

jest --maxWorkers 1
<块引用>

jest -w 1 也可以用作别名。

好处是,通过像使用 runInBand 那样采用任何特殊的相同 JS-context-all-around 假设(例如在各种配置中/ 环境设置文件),如果可能的话,这将阻止您在未来接受并行性。

答案 4 :(得分:2)

它对我来说很有效,可确保将顺序运行的各个模块测试完全分开:

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()
})

答案 5 :(得分:1)

是的,您也可以按特定顺序运行所有测试,但通常您的测试应该是独立的,因此我强烈建议不要依赖任何特定顺序。话虽如此,可能存在控制测试订单的有效案例,因此您可以这样做:

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

  • "scripts": {"test": "jest --runInBand"}

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

    __tests__

    test_suites

    test1.js

    test2.js

  • package.json 中配置 jest 以忽略此 test_suites 文件夹: "jest": { "testPathIgnorePatterns": ["/test_suites"] }

  • __tests__ 下创建一个新文件,例如tests.js - 这是现在唯一可以实际运行的测试文件。

  • tests.js 中,require 中的各个测试文件按您要运行的顺序排列:

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

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

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

答案 6 :(得分:0)

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', () => {}});
}

答案 7 :(得分:0)

来自笑话documentation

<块引用>

Jest 在执行之前执行测试文件中的所有描述处理程序 任何实际测试。这是进行设置和设置的另一个原因 在 before* 和 after* 处理程序中拆解,而不是在 描述块。

<块引用>

一旦描述块完成,默认情况下 Jest按顺序运行所有测试 在收集阶段遇到,等待每个完成并被 在继续之前整理好。

看看 jest 网站给出的例子。

答案 8 :(得分:0)

以防万一有人想在 package.json 选项中保留所有 jest 配置。

runInBand 似乎不是有效的配置选项。这意味着您最终可能会得到以下似乎并非 100% 完美的设置。

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

但是,您可以使用 ma​​xWorkers 选项添加 runInBand,如下所示:

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

答案 9 :(得分:0)

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

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

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

     module.exports = {
       testSequencer: "./__e2e__/jest/customSequencer.js",
       projects: [{
         "rootDir": "<rootDir>/__e2e__",
         "displayName": "end-to-end",
         ...
    

    这里,我明确添加了 displayNameend-to-end,即 以后会用像往常一样,您可以拥有任意数量的项目,但是 我有两个,一个用于普通单元测试,一个用于端到端。

    请注意,testSequencer 字段必须是全局的。如果你附上它 对于一个项目,它会被验证但随后被默默忽略。那是一个 开玩笑的决定让测序适合运行多个项目。

  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 顺序在最后运行端到端测试,为我的端到端测试提供额外的稳定性,使用户模型能够按照他们需要的顺序运行。

>