我通过npm test运行笑话测试。Jest默认情况下并行运行测试。是否有办法使测试按顺序运行?
npm test
我有一些测试调用依赖于更改当前工作目录的第三方代码。
CLI选项有文档记录,也可以通过运行jest --help命令来访问。
jest --help
你会看到你正在寻找的选项:--runInBand。
--runInBand
我仍在熟悉Jest,但似乎描述块是同步运行的,而测试块是异步运行的。我在一个外部描述中运行多个描述块,看起来像这样:
describe describe test1 test2 describe test3
在这种情况下,test3直到test2完成才会运行,因为test3位于包含test2的描述块之后的描述块中。
test3
test2
这对我来说很有效,确保了模块测试的有序运行:
1)将测试保存在分开的文件中,但没有spec/test命名。
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运行:
testToRunSequentially.test.js
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可以防止一组测试中的设置/拆除/清理等问题干扰其他测试:
package.json
"scripts": {"test": "jest --runInBand"}
__tests__
test_suites
test1.js
test2.js
"jest": { "testPathIgnorePatterns": ["/test_suites"] }
tests.js
require
require('./test_suites/test1.js');
require('./test_suites/test2.js');
请注意——这将导致测试中的afterAll()在所有测试完成后运行。从本质上讲,它破坏了测试的独立性,应该在非常有限的场景中使用。
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
所以除了--runInBand,我做了下面的事情。顺便说一下,我在一个存储库中使用了单独的项目。
jest.config.js
module.exports = { testSequencer: "./__e2e__/jest/customSequencer.js", projects: [{ "rootDir": "<rootDir>/__e2e__", "displayName": "end-to-end", ...
displayName
end-to-end
注意testSequencer字段必须是全局的. c。如果你附上它 对于一个项目,它将被验证,但随后将被默默地忽略。这是一个 开玩笑的决定,使排序更好地运行多个项目
testSequencer
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的新手,正在寻找一个完整的,循序渐进的例子,如何让一个特定的测试文件总是在第一个或最后一个运行,下面是:
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;
{ "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 } }
额外的好处:你还可以按字母顺序、文件夹名等顺序排列测试文件。只需修改“testSequencer.js"文件到您的偏好,并返回一个与"test "格式相同的数组;数组,它是主“sort”的参数;发挥作用,你就会好起来。
Jest按照在收集阶段遇到的顺序连续运行所有测试
你可以利用它创建特殊的测试文件alltests.ordered-test.js:
alltests.ordered-test.js
import './first-test' import './second-test' // etc.
并添加一个带有testMatch的jest配置,它将使用该文件名运行测试。
testMatch
这将按该顺序加载每个文件,从而以相同的顺序执行它们。