使用测试库中的“屏幕”时,如何在单个文件中并行运行测试?

问题描述 投票:0回答:1

我正在将React测试库jsdomVitest一起使用。我正在尝试在一个文件中运行多个单元测试,但

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')
  })
})

Parallelism test working

但是如果我使用

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')
  })
})

Parallelism not working

Failure details

reactjs react-testing-library jsdom vitest
1个回答
0
投票

总结:

  • 为了使测试按顺序工作,我在每次测试后错过了
    cleanup
    调用。
  • 如果通过
    jsdom
    环境使用
    vitest
    ,则无法避免在 单个文件 中进行测试重用它。也许直接设置
    jsdom
    就可以解决这个问题。
  • 默认情况下,单独文件中的测试与隔离环境并行运行,包括
    jsdom
    DOM。

我相信我可以使用

getByText(renderResult.container, 'foo')
,因为它不是正确的用法。相反,我应该使用
renderResult.getByText('foo')
,它会遇到同样的问题。
renderResult.container
方法无法找到例如弹出窗口。此外,我提供的示例中的测试是按顺序运行的,因为
vitest
--sequence.concurrent
默认为
false

要真正使其至少按顺序工作,必须进行清理。

该工具试图阻止我通过 ESLint 警告添加任何清理:

但是,一旦我忽略了所有 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
,它们的环境是隔离的。

© www.soinside.com 2019 - 2024. All rights reserved.