在Jest中有条件地运行测试

jogvjijk  于 2023-02-10  发布在  Jest
关注(0)|答案(4)|浏览(202)

我一直在比较函数式范例和面向对象范例。
作为其中的一部分-我想做一些性能测试。
我有一些测试,现在看起来像这样:

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

现在,我只是打印这段代码运行的时间(大约5000 ms)。
我喜欢将Jest用于它提供的所有Assert和模拟功能,以及它的实时重载等。
但是,我不希望一直进行这些测试,我会运行create一个npm脚本,如npm test:performance,并且仅在存在环境变量或类似环境变量时才运行这些测试。
做这件事的最好方法是什么?

628mspwn

628mspwn1#

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

describe('suite name', () => {
  itif(true)('test name', async () => {
    // Your test
  });
});
pxy2qtax

pxy2qtax2#

与公认答案的思路相同:

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

j2datikz3#

这是对已接受帖子的一个小改动,但如果我们将Jest的test.skip(...)与现代JS由于spread operator而允许的那种盲参数转发结合起来,我们可以得到一个更干净的解决方案,有条件地运行测试,同时让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");
  });
});

这是 typescript 版本

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脚本中,但是,我们需要确保把这个标志转发到我们的脚本中,而不是转发到jest或npm中:

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

这看起来有点奇怪,而且确实有点奇怪,但这是参数转发在npm脚本中工作的结果:
1.第一个--告诉 npm 它需要转发后面的内容,而不是解释该标志本身(实际上:这使得NPM运行jest somedir -- --run-long)。
1.第二个--告诉 jest,它需要转发后面的内容,而不是将其视为自身的运行时标志,以便 * 我们的脚本 * 能够在其process.argv列表中看到它(因此我们调用ourscript --run-long)。
一个常见的错误是忘记了第二个--,这将导致一个有趣的错误,它不会告诉您忘记了两个破折号,并且根本没有测试运行。

brccelvz

brccelvz4#

这里有一个解决方案,创建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();
    }
  );
});

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

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

相关问题