我正在将React测试库与jsdom和Vitest一起使用。我正在尝试在一个文件中运行多个单元测试,但
screen
变量似乎具有来自所有测试的所有 render
调用的输出,导致重复。 screen
推荐如下:
但是,如果我使用显式容器的过时方法,我不会遇到这个问题。
如何使用
screen
并并行运行测试,确保每个测试都有自己独立的 DOM?
这有效,两个测试都通过(它们按顺序运行),但它不使用
screen
:
import { render, getByText } from '@testing-library/react'
import { describe, test } from 'vitest'
describe('Parallelism test', () => {
test('Render 1', () => {
const renderResult = render(<div>foo</div>)
getByText(renderResult.container, 'foo')
})
test('Render 2', () => {
const renderResult = render(<div>foo</div>)
getByText(renderResult.container, 'foo')
})
})
但是如果我使用
screen
来顺序运行测试,我会遇到失败:
import { render, screen } from '@testing-library/react'
import { describe, test } from 'vitest'
describe('Parallelism test', () => {
test('Render 1', () => {
render(<div>foo</div>)
screen.getByText('foo')
})
test('Render 2', () => {
render(<div>foo</div>)
screen.getByText('foo')
})
})
总结:
cleanup
调用。jsdom
环境使用 vitest
,则无法避免在 单个文件 中进行测试重用它。也许直接设置jsdom
就可以解决这个问题。jsdom
DOM。我相信我可以使用
getByText(renderResult.container, 'foo')
,因为它不是正确的用法。相反,我应该使用 renderResult.getByText('foo')
,它会遇到同样的问题。 renderResult.container
方法无法找到例如弹出窗口。此外,我提供的示例中的测试是按顺序运行的,因为 vitest
的 --sequence.concurrent
默认为 false
。
要真正使其至少按顺序工作,必须进行清理。
该工具试图阻止我通过 ESLint 警告添加任何清理:
cleanup
文档:
如果您的测试框架(例如 mocha、Jest 或 Jasmine)将全局 afterEach() 函数注入到测试环境中,则会自动调用此函数。如果没有,您将需要在每次测试后调用 cleanup() 。
但是,一旦我忽略了所有 ESLint 警告并添加了清理,测试现在可以按顺序运行:
import { render, screen, cleanup } from '@testing-library/react'
import { describe, test, afterEach } from 'vitest'
describe('Parallelism test', () => {
afterEach(() => {
console.log('afterEach cleanup')
cleanup()
})
test('Render 1', async () => {
console.log('r1')
render(<div>foo</div>)
screen.getByText('foo')
await delay(1000)
})
test('Render 2', async () => {
console.log('r2')
render(<div>foo</div>)
screen.getByText('foo')
await delay(1000)
})
})
async function delay(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms))
}
但是,当使用
--sequence.concurrent=true
运行时,它会以通常的方式失败。
fileParallelism
设置为 true
并行运行,并且根据 poolOptions.threads.isolate
设置为 true
,它们的环境是隔离的。