如何顺序运行Jest测试?

Mar*_*cek 112 jestjs

我正在通过Jest测试npm test.Jest默认并行运行测试.有没有办法让测试依次运行?

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

ncu*_*ery 180

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

然后,您将看到您正在寻找的选项:--runInBand.

  • 不幸的是,执行顺序无法控制的事实使得Jest对于集成测试几乎没用. (29认同)
  • @MartinKonicek`npm test - --runInBand`是正确的. (11认同)
  • @NicoVanBelle这仅仅是您对足够复杂的有状态系统进行真正的端到端测试的价格。我对替代品持开放态度,但是我还没有看到一种解决方案,该解决方案既不涉及天真地换掉堆栈的关键部分,又不涉及测试之间的数据库重置速度过慢。这并不意味着Jest是一个不好的工具,只是针对这种特定测试的错误工具。 (10认同)
  • @Evan您需要按特定顺序运行测试的事实是一种气味。 (7认同)
  • @埃文B。好消息!从 Jest 版本 24.7.0 开始,您现在可以提供自己的 `TestSequencer` 并设置您想要的任何顺序:https://github.com/facebook/jest/issues/6194#issuecomment-479356058 我们创建了一个 `RandomTestSequencer`然后只需使用配置 `testSequencer: 'path/to/RandomTestSequencer.js'` 进行设置。 (6认同)
  • 非常感谢!它是`npm test --runInBand`吗?Offtopic:不确定"乐队"这个名字的来源.--run顺序可能会更有意义:) (4认同)

kim*_*y82 14

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

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

"scripts": {
    "test": "jest  --runInBand"
},
...
"jest": {
    "verbose": true,
    "forceExit": true,
    "preset": "ts-jest",
    "testURL": "http://localhost/",
    "testRegex": "\\.test\\.ts$",
    ...
  }
...
Run Code Online (Sandbox Code Playgroud)

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

  "scripts": {
        "test": "jest"
    },
    ...
    "jest": {
        "verbose": true,
        "maxWorkers": 1,
        "forceExit": true,
        "preset": "ts-jest",
        "testURL": "http://localhost/",
        "testRegex": "\\.test\\.ts$",
        ...
      }
    ...
Run Code Online (Sandbox Code Playgroud)


Stu*_*att 14

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

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

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

     module.exports = {
       testSequencer: "./__e2e__/jest/customSequencer.js",
       projects: [{
         "rootDir": "<rootDir>/__e2e__",
         "displayName": "end-to-end",
         ...
    
    Run Code Online (Sandbox Code Playgroud)

    在这里,我明确添加了displayNameto be end-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;
    
    Run Code Online (Sandbox Code Playgroud)

这个组合按照 Jest 的喜好运行所有常规测试,但总是以 alpha 顺序在最后运行端到端测试,从而为我的端到端测试提供了用户模型所需的额外稳定性。


Joa*_*ous 12

使用串行测试运行器:

npm install jest-serial-runner --save-dev
Run Code Online (Sandbox Code Playgroud)

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

module.exports = {
   ...,
   runner: 'jest-serial-runner'
};
Run Code Online (Sandbox Code Playgroud)

您可以使用项目功能将其仅应用于测试的子集。见https://jestjs.io/docs/en/configuration#projects-arraystring--projectconfig


Sup*_*rah 9

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

describe
    describe
        test1
        test2

    describe
        test3
Run Code Online (Sandbox Code Playgroud)

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

  • 也许它仍然会并行运行。 (4认同)
  • 这看起来很像不安全的实现细节。 (3认同)
  • 这对于我测试有状态的 WebSocket 服务器(连接、登录、注销)非常有效,显然它必须以正确的顺序运行。不过,外部的“describe”不是必需的。 (2认同)

kmn*_*wak 8

它为我工作,确保按顺序运行良好分离的模块测试:

1)将测试保存在单独的文件中,但不要spec/test命名。

|__testsToRunSequentially.test.js
|__tests
   |__testSuite1.js
   |__testSuite2.js
   |__index.js
Run Code Online (Sandbox Code Playgroud)

2)具有测试套件的文件也应如下所示(testSuite1.js):

export const testSuite1 = () => describe(/*your suite inside*/)
Run Code Online (Sandbox Code Playgroud)

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

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

describe('sequentially run tests', () => {
   testSuite1()
   testSuite2()
})
Run Code Online (Sandbox Code Playgroud)

  • 您不需要使用 --runInBand 运行,因为您已经有两个测试套件。子测试套件按顺序执行。 (3认同)

Mor*_*esh 7

复制自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)
Run Code Online (Sandbox Code Playgroud)

signup.js

export const signuptests = () => {
     it('Should have login elements', () => {});
     it('Should Signup', () => {}});
}
Run Code Online (Sandbox Code Playgroud)

login.js

export const logintests = () => {
    it('Should Login', () => {}});
}
Run Code Online (Sandbox Code Playgroud)


d4v*_*idi 6

虽然--runInBand有效,但它比您需要的要多一些 - 根据 Jest 的文档:

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

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

尽管如此,为了保留该核心范式并按顺序运行,您可以使用--maxWorkers 1,它只会将并发运行的工作人员的数量限制为 1(从而导致顺序运行):

jest --maxWorkers 1
Run Code Online (Sandbox Code Playgroud)

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

这样做的好处是,通过采用任何特殊的相同 JS-context-all-around 假设runInBand(例如在各种配置/环境设置文件中),您可以更安全地使用它,这将使您无法在未来,如果可能的话。


Chr*_*row 6

是的,您也可以按特定顺序运行所有测试,尽管通常您的测试应该是独立的,因此我强烈警告不要依赖任何特定顺序。话虽如此,可能存在控制测试顺序的有效情况,因此您可以这样做:

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

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

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

    __tests__

    test_suites

    test1.js

    test2.js

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

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

  • 在 中tests.jsrequire各个测试文件按照您想要运行的顺序排列:

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

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

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


Onu*_*vik 5

如果您是 Jest 的新手,并且正在寻找有关如何使特定测试文件始终首先或最后运行的完整分步示例,请参阅以下内容:

  1. 在您想要的任何路径中创建一个名为“testSequencer.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 (target_test_index == -1) {
            return tests;
        }

        const target_test = tests[target_test_index];

        const ordered_tests = tests.slice();

        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;
Run Code Online (Sandbox Code Playgroud)
  1. 在 package.json jest 配置中将“maxWorkers”选项设置为“1”。另外,将“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
  }
}
Run Code Online (Sandbox Code Playgroud)
  1. 运行 npm test 并观察每个测试文件将在每个测试文件完成后一一运行。你牺牲了一些时间,但这样你保证了顺序。

奖励:您还可以按字母顺序、文件夹名称等对测试文件进行排序。只需根据您的喜好修改“testSequencer.js”文件,并返回一个与“tests”数组格式相同的数组,该数组是您的测试的参数主要的“排序”功能,你会很好的。