我有一个React
+vite
应用程序,我正在为它编写测试,以涵盖应用程序启动时的前端路由重定向逻辑。
路由由react-router
v6处理,并且与路由相关联的所有组件都封装在React.lazy
中。测试由vitest
运行,我使用react-testing-library
助手
所有的测试都很相似,看起来像这个
it('Redirects from app root to red room if the user has a red shirt', async () => {
getUser.mockReturnValue(redShirtUser);
render(MyTestedComponent, { wrapper });
await waitFor(() => expect(screen.getByText('Welcome to the red room'));
expect(history.location.pathname).toBe('/red-room');
});
然而,其中一项测试比其他测试花费的时间要长得多,以至于waitFor
超时。我可以为waitFor
指定更长的超时时间,但它仍然无法在CI上可靠运行。如果测试是其文件中唯一的测试/唯一正在执行的测试,也会发生这种情况。
我已经将缓慢的部分(通过console.log
调试的魔力(缩小为懒惰的import()
语句——在导入和执行模块之前需要花费很多(秒(时间。
如何调试?是否有已知的因素会导致(懒惰的(进口变得缓慢?
Node的模块解析非常慢。因此,如果您的脚本导入/需要大量其他脚本/依赖项,那么您的启动时间将非常缓慢。
如果你在测试中进行惰性导入,那么这个启动时间将作为测试的一部分。
您可以通过在测试文件的顶部或在设置阶段预加载脚本来避免这种情况。
在文件顶部预加载脚本是最简单的方法,
只需放入import './path';
或require('./path');
只有当您经常运行一些选择测试而不是所有测试时,启动阶段的预加载才有用,因为您不想预加载不会被测试的脚本。
在jest
中,这是使用beforeAll()
完成的,类似于:
describe('my thing', () =>
{
beforeAll(() => import('./path'))
// alternatively you can use require:
beforeAll(() => require('./path'))
// ...your tests...
})
我从未使用过vitest
,所以我不知道那里的设置阶段是如何配置的。我只找到了这个,但它看起来像是一个全局配置,可能最好将导入放在测试脚本的顶部,然后在全局配置中进行。
旁注:
加载一个需要几秒钟时间的组件可能表明它正在导入不需要的东西
当您在同一个文件中有许多组件时,或者当您没有将共享代码移动到单独的文件中时,通常会发生这种情况
在一个文件中有很多不相关的代码对Node来说是个问题,因为它不能进行任何树抖动,也不会跳过未使用的导入。
此外,如果组件并不总是渲染其所有子组件,那么您也可以对这些子组件使用惰性导入。
在10之前的版本中,我们可以使用waitForElement,这将花费更少的时间。有关更多详细信息或详细解释,请观看https://www.youtube.com/watch?v=lfb5jvHq9c4视频在版本10之后,您使用的waitFor都是正确的。感谢您更正@agos。编辑评论以避免其他用户遇到麻烦。但除此之外,确保使用try-catch在该组件中使用正确的错误处理也同样重要。