You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Testing Library的screen并行运行单文件测试并隔离DOM

解决React Testing Library+Vitest并行测试时screen共享DOM的问题

问题根源

Vitest默认并行执行同文件内的测试时,会共享全局jsdom环境。screen的查询基于全局document,所以多次render的内容会叠加在同一个DOM中,导致查询时出现重复匹配而失败。而使用显式容器查询时,范围被限定在当前测试的渲染容器内,不受全局DOM污染影响。

可行解决方案

1. 开启Vitest的独立模块模式(推荐)

在vitest.config.js中配置isolatedModules: true,让每个测试文件拥有完全独立的执行上下文,全局document和screen会在每个测试文件运行前自动重置:

import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    environment: 'jsdom',
    isolatedModules: true,
  },
})

2. 手动清理DOM

如果不想启用独立模块,可在每个测试结束后调用React Testing Library的cleanup方法,清空全局DOM:

import { render, screen, cleanup } from '@testing-library/react'
import { describe, test, afterEach } from 'vitest'

describe('Parallelism test', () => {
  afterEach(() => {
    cleanup()
  })

  test('Render 1', () => {
    render(<div>foo</div>)
    screen.getByText('foo')
  })

  test('Render 2', () => {
    render(<div>foo</div>)
    screen.getByText('foo')
  })
})

注:React Testing Library在Jest中默认自动执行cleanup,但Vitest没有这个默认行为,需手动配置。

3. 限定查询范围(过渡方案)

通过within工具将查询范围限定在当前测试的渲染容器内,既保留类似screen的查询语法,又避免全局DOM污染:

import { render, within } from '@testing-library/react'
import { describe, test } from 'vitest'

describe('Parallelism test', () => {
  test('Render 1', () => {
    const { container } = render(<div>foo</div>)
    within(container).getByText('foo')
  })

  test('Render 2', () => {
    const { container } = render(<div>foo</div>)
    within(container).getByText('foo')
  })
})

此方法本质和旧的显式容器查询逻辑一致,仅为了兼容screen风格的语法,不推荐长期使用。

验证

采用上述任意方案后,重新运行并行测试,每个测试的DOM会被独立隔离,screen查询不会再出现重复内容导致的失败。

内容的提问来源于stack exchange,提问作者Konrad Jamrozik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 02:44:56