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

时间:2017-11-14 16:53:25

标签: javascript jestjs create-react-app

默认情况下,

Jest并行运行您的测试套件,但有一个标志(--runInBand)允许您按顺序运行整个套件(如指出here

我有一些测试无法并行运行,但是按顺序运行整个套件需要花费更长的时间,所以我的问题是,是否有办法只运行某些测试(例如为这些测试或类似的东西设置标志。)

4 个答案:

答案 0 :(得分:8)

我也需要相同的功能。我有大量要运行的Jest集成测试套件。但是,由于需要设置和拆除共享资源,因此某些不能并行运行。所以,这是我想出的解决方案。

我从以下位置更新了package.json脚本:

{
  ...
  "scripts": {
    ...
    "test": "npm run test:unit && npm run test:integration",
    "test:integration": "jest --config=__tests__/integration/jest.config.js",
    "test:unit": "jest --config=__tests__/unit/jest.config.js"
  },
  ...
}

{
  ...
  "scripts": {
    ...
    "test": "npm run test:unit && npm run test:integration",
    "test:integration": "npm run test:integration:sequential && npm run test:integration:parallel",
    "test:integration:parallel": "jest --config=__tests__/integration/jest.config.js",
    "test:integration:sequential": "jest --config=__tests__/integration/jest.config.js --runInBand",
    "test:unit": "jest --config=__tests__/unit/jest.config.js"
  },
  ...
}

然后我从{p>更新了__tests__/integration/jest.config.js

module.exports = {
  // Note: rootDir is relative to the directory containing this file.
  rootDir: './src',
  setupFiles: [
    '../setup.js',
  ],
  testPathIgnorePatterns: [
    ...
  ],
};

const Path = require('path');

const { defaults } = require('jest-config');
const klawSync = require('klaw-sync')
const mm = require('micromatch');

// Note: rootDir is relative to the directory containing this file.
const rootDir = './src';
const { testMatch } = defaults;

// TODO: Add the paths to the test suites that need to be run
// sequentially to this array.
const sequentialTestPathMatchPatterns = [
  '<rootDir>/TestSuite1ToRunSequentially.spec.js',
  '<rootDir>/TestSuite2ToRunSequentially.spec.js',
  ...
];

const parallelTestPathIgnorePatterns = [
  ...
];

let testPathIgnorePatterns = [
  ...parallelTestPathIgnorePatterns,
  ...sequentialTestPathMatchPatterns,
];

const sequential = process.argv.includes('--runInBand');
if (sequential) {
  const absRootDir = Path.resolve(__dirname, rootDir);
  let filenames = klawSync(absRootDir, { nodir: true })
    .map(file => file.path)
    .map(file => file.replace(absRootDir, ''))
    .map(file => file.replace(/\\/g, '/'))
    .map(file => '<rootDir>' + file);
  filenames = mm(filenames, testMatch);
  testPathIgnorePatterns = mm.not(filenames, sequentialTestPathMatchPatterns);
}

module.exports = {
  rootDir,
  setupFiles: [
    '../setup.js',
  ],
  testMatch,
  testPathIgnorePatterns,
};

更新后的jest.config.js取决于jest-configklaw-syncmicromatch

npm install --save-dev jest-config klaw-sync micromatch

现在,如果只想运行需要顺序运行的测试,则可以运行npm run test:integration:sequential

或运行npm run test:integration:parallel进行并行测试。

或运行npm run test:integration首先运行顺序测试。然后,完成后,将运行并行测试。

或者运行npm run test来运行单元测试和集成测试。

注意:我在本机和集成测试中使用的目录结构如下:

__tests__
  integration
    src
      *.spec.js
      *.test.js
    jest.config.js
  unit
    src
      *.spec.js
      *.test.js
    jest.config.js

答案 1 :(得分:0)

使用串行测试运行器:

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

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

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

您可以使用项目功能为不同的测试提供不同的配置。

答案 2 :(得分:0)

这有点麻烦,但是我认为值得发布我的最终配置。我遇到了同样的问题,并扩展了Joachim Lous'Fishball's的答案,以获得令人满意的结果。这是我的最终设置:

我的项目的简短目录列表:

├── src
│   ├── index.ts
│   ├── Io.ts
│   ├── Modules
│   │   └── index.ts
│   └── .....
└── tests
    ├── EndToEnd
    │   ├── Fixtures.ts
    │   ├── Mq.spec.ts
    │   ├── LegalEntities.spec.ts
    │   └── Utils.ts
    └── UnitTests
        ├── LegalEntities.spec.ts
        ├── Assets.spec.ts
        └── Utils.ts

其中包含我的玩笑配置的package.json文件(缩写):

{
  "name": "my-project",
  "scripts": {
    "build": "scripts/build",
    "check": "tsc --noEmit",
    "test": "jest"
  },
  "....": "....",
  "jest": {
    "projects": [
      {
        "displayName": "unit-tests",
        "testEnvironment": "node",
        "verbose": true,
        "testMatch": [
          "<rootDir>/tests/**/*.spec.ts",
          "!**/EndToEnd/**/*.spec.ts"
        ],
        "transform": {
          "^.+\\.tsx?$": "ts-jest"
        }
      },
      {
        "displayName": "e2e-tests",
        "testEnvironment": "node",
        "verbose": true,
        "maxWorkers": 1,
        "testMatch": [
          "<rootDir>/tests/EndToEnd/**/*.spec.ts"   
        ],
        "transform": {
          "^.+\\.tsx?$": "ts-jest"
        }
      }
    ]
  }
}

注意事项:

  • 开玩笑地使用projects键时,我不得不将 all 配置移到各个项目块中。使用项目配置与使用全局配置是互斥的。
  • 我没有使用其他答案中提到的runner指令。相反,我使用maxWorkers选项将执行限制为1个工作程序(即,固有地是串行的)。这意味着我不必使用更多的依赖项。
  • 由于某种原因,我的单元测试中的否定语法有些挑剔。我想将单元测试指定为不在EndToEnd目录中的所有测试,这花了我一些时间来开玩笑地正确进行此操作。

感谢其他所有人的可行起点。希望这对其他人有帮助!

答案 3 :(得分:-2)

一种更简单的解决方法是使用Promises明确排序需要此测试的测试:

describe('ordered tests', async () => {
    let resolveFirstStepCompleted: (() => void);
    const firstStepCompletedPromise = new Promise((resolve) => {
        resolveFirstStepCompleted = resolve;
    }

    it('first step', async () => {
        // do something
        resolveFirstStepCompleted();
    });

    it('second step that depends on the first step', async () => {
        await firstStepCompletedPromise;
        // do something else
    });


    it('a thirth that depends only on the first step, not on the second', async () => {
        await firstStepCompletedPromise;
        // do something else
    });
});