我正在通过 npm test
运行 Jest 测试。 Jest 默认并行运行测试。有没有办法让测试按顺序运行?
我有一些测试调用依赖于更改当前工作目录的第三方代码。
我仍然熟悉 Jest,但似乎描述块同步运行,而测试块异步运行。我在看起来像这样的外部描述中运行多个描述块:
describe
describe
test1
test2
describe
test3
在这种情况下,在 test2
完成之前,test3
不会运行,因为 test3
位于包含 test2
的描述块之后的描述块中。
describe
不是必需的。
它对我有用,确保顺序运行很好地分离到模块测试:
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
--testRunner
参数一起使用吗?这仅适用于 CI/CD,我不想在配置中修改我的跑步者。另外,我不是在谈论 --runInBand
选项。
从 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
解决方案对我来说还不够。是的:它确保在测试套件/文件中该顺序有效,但文件本身按照 Jest 为并行化而选择的顺序运行,并且不容易控制。如果您需要测试套件本身的稳定顺序,这就是您可以做到的。
所以除了--runInBand
之外,我还做了以下事情。顺便说一句,我在一个存储库中为此使用了单独的项目。
我的 jest.config.js 看起来像这样: module.exports = { testSequencer: "./__e2e__/jest/customSequencer.js", projects: [{ "rootDir": "
这个组合运行 Jest 喜欢的所有常规测试,但始终以 alpha 顺序在最后运行端到端测试,为我的端到端测试提供额外的稳定性,让用户模型按照他们需要的顺序运行。
以防万一有人想在 package.json 选项中保留所有 jest 配置。
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$",
...
}
...
是的,您也可以按特定顺序运行所有测试,尽管通常您的测试应该是独立的,所以我强烈警告不要依赖任何特定的顺序。话虽如此,可能存在控制测试顺序的有效案例,因此您可以这样做:
在运行 jest 时添加 --runInBand 作为选项,例如在 package.json 中。这将按顺序而不是并行(异步)运行测试。使用 --runInBand 可以防止一组测试中的设置/拆卸/清理等问题干扰其他测试:
“脚本”:{“测试”:“开玩笑--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('./test_suites/test1.js');要求('./test_suites/test2.js');
注意 - 这将导致测试中的 afterAll()
在 所有 测试完成后运行。从本质上讲,它打破了测试的独立性,应该在非常有限的场景中使用。
如果您是 Jest 的新手,并且正在寻找一个完整的分步示例,说明如何使特定的测试文件始终首先或最后运行,这里是:
在您想要的任何路径中创建一个名为“testSequencer.js”的文件。将下面的代码粘贴到该文件中。
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;
在您的 package.json 笑话配置中将“maxWorkers”选项设置为“true”。此外,将“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
}
}
运行 npm test 并观察每个测试文件将在每个完成后一个接一个地运行。您牺牲了一些时间,但您以这种方式保证了订单。
奖励:您还可以按字母顺序、文件夹名称等对测试文件进行排序。只需根据您的偏好修改“testSequencer.js”文件,并返回一个与“tests”数组格式相同的数组,这是您的参数主要的“排序”功能,你会很好。
从笑话 documentation:
Jest 在执行任何实际测试之前执行测试文件中的所有描述处理程序。这是在 before* 和 after* 处理程序内部而不是在 describe 块内部进行设置和拆卸的另一个原因。
一旦描述块完成,默认情况下,Jest 按照它们在收集阶段遇到的顺序依次运行所有测试,等待每个测试完成并在继续之前进行整理。
看看这个笑话网站给出的例子。
npm test --runInBand
吗?题外话:不知道“乐队”这个名字是从哪里来的。 --runSequentially 可能更有意义:)npm test -- --runInBand
是正确的。