Jest测试需要75秒,但每次测试只需要几毫秒



在我们的CI(github(工作流中,我有一个Jest输出,看起来像这样。

PASS a/b/c.spec.tsx (75.856 s)
Test
✓ should a (45 ms)
✓ should b (53 ms)
✓ should c (19 ms)
✓ should d (13 ms)
✓ should e (12 ms)
✓ should f (14 ms)
✓ should g (18 ms)

在我的本地设置中,它需要7秒。我删除了多少个单独的测试似乎也无关紧要,时间大致相同(这是有道理的,每个测试只有几毫秒(。我的测试就像这个

import React from 'react';
import { render, screen } from '@testing-library/react';
import Foo from './foo';
describe('Test', () => {
it('should a', () => {
const { baseElement } = render(
<Foo
text="SomeText"
number={0}
moretext="More Text"
/>
);
expect(baseElement).toBeTruthy();
});
it('should b', () => {
const { baseElement } = render(
<Foo
text="SomeText"
number={0}
moretext="More Text"
/>
);
expect(baseElement).toBeTruthy();
expect(baseElement.querySelector('h2')).toHaveTextContent(
'SomeText'
);
});

等等。一切都是用查询选择器完成的。不过,每次测试都很快。如果每次测试只有几毫秒,为什么在GitHub CI上运行需要75秒(持续(?在我的本地设置中,即使是7秒也很痛苦。

Jest测试也经历了同样的缓慢,尤其是在Windows环境中运行。据报道,它非常依赖于操作系统,并且需要一些时间才能启动——这显然与它在开始测试之前如何分析您的依赖关系有关,这样它们以后可以更快地运行,这解释了为什么删除测试对缩短测试时间几乎没有作用。

这里、这里和这里等都报告了多个问题,所以这是一个已知的问题,并且正在进行优化一些性能的工作,但可能也值得考虑其他测试框架,如Jasmine或Mocha。

经过大量调试后,我发现根本原因是setupFilesAfterEnv和其他安装文件,它们会为每个单独的测试文件再次运行。如果你有";昂贵的";这些文件中的迭代,或者如果您对大型库使用requireActual,这可能会导致性能下降。值得注意的是,随着测试次数的增加,性能会下降。您可能会注意到,缓冲区中的最后一个测试是最慢的,无论它们的复杂性如何,而且它们还与较大的内存堆相关联。

为了缓解这个问题,我将这些库的mock放在__mocks__目录下。这大大减少了测试时间,因为Jest只会在测试期间主动需要给定路径时执行这些mock。

例如,考虑一个名为neck-js的库。代替以下代码:

jest.mock('neck-js', () => ({
__esModule: true,
default: 'bob',
somethingElse: jest.fn(),
}));

您可以创建一个名为mocks/neck-js的目录,其中包括:

export default 'bob';
export const somethingElse = jest.fn();

尽管Jest的lint规则不鼓励这样做,但您可以直接访问导出的模拟对象、更改它们的实现或检查调用。根据我的经验,这种方法产生了一个更有组织的代码库,并且在更大的项目中更容易管理。

这并不是提高速度和减少RAM使用量的唯一方法;一位开发人员在这里提出了几个值得一看的好建议。

最新更新