在 Jest 中有条件地运行测试

dwj*_*ton 9 performance-testing jestjs

我一直在比较功能范式和面向对象范式。

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

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

it("Some long running performance test", () => {
    const result = myFunctionWithLotsOfData();       
}); 
Run Code Online (Sandbox Code Playgroud)

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

我喜欢将 Jest 用于它提供的所有断言和模拟功能,并且它是实时重新加载等。

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

做到这一点的最佳方法是什么?

Dam*_*pov 30

const itif = (condition) => condition ? it : it.skip;

describe('suite name', () => {
  itif(true)('test name', async () => {
    // Your test
  });
});
Run Code Online (Sandbox Code Playgroud)


Mik*_*ans 19

与已接受的帖子相比,有一个小小的变化,但如果我们将 Jesttest.skip(...)与现代 JS 允许的盲目参数转发(多亏了扩展运算符)结合起来,我们就可以获得一个更干净的解决方案,有条件地运行测试,同时让 Jest 知道它跳过了一些“官方方式”,不需要“functionfunction”调用:

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");
  });
});
Run Code Online (Sandbox Code Playgroud)

或者这是打字稿版本

const testIf = (condition: boolean, ...args: Parameters<typeof test>) =>
  condition ? test(...args) : test.skip(...args);
Run Code Online (Sandbox Code Playgroud)

一半的时间将运行为:

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        0.451 s, estimated 1 s
Run Code Online (Sandbox Code Playgroud)

有一半的时间它会显示:

Test Suites: 1 passed, 1 total
Tests:       1 skipped, 1 passed, 2 total
Snapshots:   0 total
Time:        0.354 s, estimated 1 s
Run Code Online (Sandbox Code Playgroud)

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

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        0.451 s, estimated 1 s
Run Code Online (Sandbox Code Playgroud)

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

Test Suites: 1 passed, 1 total
Tests:       1 skipped, 1 passed, 2 total
Snapshots:   0 total
Time:        0.354 s, estimated 1 s
Run Code Online (Sandbox Code Playgroud)

这看起来有点奇怪,也确实有点奇怪,但这是 npm 脚本参数转发工作方式的结果:

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

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


Or *_*Gal 7

与接受的答案相同:

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


sli*_*wp2 5

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

\n\n

例如,itif函数:

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

单元测试:

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

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

\n\n
PERFORMANCE_TEST=true npm t -- /Users/elsa/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/58264344/index.spec.t\n\n> jest-codelab@1.0.0 test /Users/elsa/workspace/github.com/mrdulin/jest-codelab\n> jest --detectOpenHandles "/Users/elsa/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/58264344/index.spec.ts"\n\n PASS  src/stackoverflow/58264344/index.spec.ts\n  test suites\n    \xe2\x9c\x93 functional-approach-2 perforance test (18ms)\n\n  console.info src/stackoverflow/58264344/index.spec.ts:22\n    Functional Approach 2 Performance Test\n\n  console.log src/stackoverflow/58264344/index.spec.ts:4\n    0\n\n  console.info src/stackoverflow/58264344/index.spec.ts:28\n    Length: 0\n\n  console.info src/stackoverflow/58264344/index.spec.ts:29\n    Time Taken: 5ms\n\nTest Suites: 1 passed, 1 total\nTests:       1 passed, 1 total\nSnapshots:   0 total\nTime:        5.67s, estimated 9s\n
Run Code Online (Sandbox Code Playgroud)\n\n

当值为process.env.PERFORMANCE_TEST当环境变量的值未设置

\n\n
npm t -- /Users/elsa/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/58264344/index.spec.ts\n\n> jest-codelab@1.0.0 test /Users/elsa/workspace/github.com/mrdulin/jest-codelab\n> jest --detectOpenHandles "/Users/elsa/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/58264344/index.spec.ts"\n\n PASS  src/stackoverflow/58264344/index.spec.ts\n  test suites\n    \xe2\x9c\x93 functional-approach-2 perforance test (11ms)\n\n  console.warn src/stackoverflow/58264344/index.spec.ts:11\n    [skipped]: functional-approach-2 perforance test\n\nTest Suites: 1 passed, 1 total\nTests:       1 passed, 1 total\nSnapshots:   0 total\nTime:        2.758s, estimated 5s\n
Run Code Online (Sandbox Code Playgroud)\n