有条件地在开玩笑中运行测试



我一直在比较函数范式和面向对象范式。

作为其中的一部分 - 我想做一些性能测试。

我现在有一些看起来像这样的测试:

it("Some long running performance test", () => {
const result = myFunctionWithLotsOfData();       
}); 

现在,我只是打印此代码运行所需的时间(大约 5000 毫秒(。

我喜欢使用 Jest 来实现它提供的所有断言和模拟功能,以及实时重新加载等。

但是,我不希望这些测试一直进行,我会运行创建像npm test:performance这样的 npm 脚本,并且仅在存在环境变量或类似环境变量时才运行这些测试。

最好的方法是什么?

const itif = (condition) => condition ? it : it.skip;
describe('suite name', () => {
itif(true)('test name', async () => {
// Your test
});
});

与接受的答案相同:

const maybe = process.env.JEST_ALLOW_INTEG ? describe : describe.skip;
maybe('Integration', () => {
test('some integration test', async () => {
expect(1).toEqual(1);
return;
});
});

接受帖子的一个小变化,但如果我们将 Jest 的test.skip(...)与现代 JS 允许的那种盲参数转发结合起来,这要归功于传播运算符,我们可以得到一个更干净的解决方案,有条件地运行测试,同时让 Jest 知道它跳过了一些"官方方式",而不需要"函数函数"调用:

const testIf = (condition, ...args) =>
condition ? test(...args) : test.skip(...args);
describe(`a mix of tests and conditional tests`, () => {
test(`this will always run`, () => {
expect("1").toBe("1");
});
testIf(Math.random() > 0.5, `this will only run half the time`, () => {
expect("2").toBe("2");
});
});

或者这是打字稿版本

const testIf = (condition: boolean, ...args: Parameters<typeof test>) =>
condition ? test(...args) : test.skip(...args);

一半的时间将运行为:

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        0.451 s, estimated 1 s

一半的时间它会显示:

Test Suites: 1 passed, 1 total
Tests:       1 skipped, 1 passed, 2 total
Snapshots:   0 total
Time:        0.354 s, estimated 1 s

但是为了涵盖似乎没有人包含在他们的答案中的部分,我们可以使用它来跳过长时间运行的测试,将其与"查看运行时标志process.argv"相结合:

const runLong = process.argv.includes(`--run-long`);
const testIf = (condition, ...args) =>
condition ? test(...args) : test.skip(...args);
describe(`Run tests, and long tests only if told to`, () => {
// ...
testIf(runLong, `Some long-running test, skip if --run-long is not set`, () => {
// a test that runs for a long time here
});
});

然后我们可以把这个运行时标志放在我们的 npm 脚本中。但是,我们需要确保将该标志转发到我们的脚本上,而不是开玩笑或转发到 npm:

...
"scripts": {
...
"test": "jest somedir",
"test:long": "npm run test -- -- --run-long",
...
},
...

这看起来有点奇怪,而且有点奇怪,但这是参数转发如何为 npm 脚本工作的结果:

  1. 第一个--告诉npm它需要转发以下内容,而不是解释该标志本身(实际上:这使得 npm 运行jest somedir -- --run-long(。
  2. 第二个--告诉jest它需要转发以下内容,而不是将其视为自身的运行时标志,以便我们的脚本可以在其process.argv列表中看到它(以便我们调用ourscript --run-long(。

一个常见的错误是忘记第二个--,这会导致一个有趣的错误,它不会告诉您只是忘记了两个破折号,并且根本没有运行任何测试。

这是一个解决方案,创建itif函数,以便我们可以根据某些条件运行单元测试。

例如,itif函数:

export const itif = (name: string, condition: () => boolean | Promise<boolean>, cb) => {
it(name, async done => {
if (await condition()) {
cb(done);
} else {
console.warn(`[skipped]: ${name}`);
done();
}
});
};

该单元测试:

describe('test suites', () => {
itif(
'functional-approach-2 perforance test',
async () => process.env.PERFORMANCE_TEST === 'true',
done => {
console.info('Functional Approach 2 Performance Test');
const t0 = Date.now();
const m0 = getMemory();
const li0 = instantiateFanRecursive(20, 2, 0, 0, 1, 1, 2, 1);
const r0 = getDrawablesFromLineInstances(li0);
printMemory(getMemory() - m0);
console.info(`Length: ${r0.length}`);
console.info(`Time Taken: ${Date.now() - t0}ms`);
done();
}
);
});

当环境变量的值等于'true'时运行单元测试process.env.PERFORMANCE_TEST结果:

PERFORMANCE_TEST=true npm t -- /Users/elsa/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/58264344/index.spec.t
> jest-codelab@1.0.0 test /Users/elsa/workspace/github.com/mrdulin/jest-codelab
> jest --detectOpenHandles "/Users/elsa/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/58264344/index.spec.ts"
PASS  src/stackoverflow/58264344/index.spec.ts
test suites
✓ functional-approach-2 perforance test (18ms)
console.info src/stackoverflow/58264344/index.spec.ts:22
Functional Approach 2 Performance Test
console.log src/stackoverflow/58264344/index.spec.ts:4
0
console.info src/stackoverflow/58264344/index.spec.ts:28
Length: 0
console.info src/stackoverflow/58264344/index.spec.ts:29
Time Taken: 5ms
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        5.67s, estimated 9s

如果未设置环境变量的值process.env.PERFORMANCE_TEST则不要运行单元测试:

npm t -- /Users/elsa/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/58264344/index.spec.ts
> jest-codelab@1.0.0 test /Users/elsa/workspace/github.com/mrdulin/jest-codelab
> jest --detectOpenHandles "/Users/elsa/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/58264344/index.spec.ts"
PASS  src/stackoverflow/58264344/index.spec.ts
test suites
✓ functional-approach-2 perforance test (11ms)
console.warn src/stackoverflow/58264344/index.spec.ts:11
[skipped]: functional-approach-2 perforance test
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.758s, estimated 5s

最新更新