vitest-browser-vue
社区 vitest-browser-vue 包在 浏览器模式 中渲染 Vue 组件。
import { render } from 'vitest-browser-vue'
import { expect, test } from 'vitest'
import Component from './Component.vue'
test('counter button increments the count', async () => {
const screen = await render(Component, {
props: {
initialCount: 1,
}
})
await screen.getByRole('button', { name: 'Increment' }).click()
await expect.element(screen.getByText('Count is 2')).toBeVisible()
})WARNING
这个库的灵感来自 @testing-library/vue。
如果你之前在测试中使用过 @testing-library/vue,你可以继续使用它,但是 vitest-browser-vue 包提供了一些 @testing-library/vue 所缺乏的、浏览器模式独有的优势:
vitest-browser-vue 返回的 API 能与内置的 定位器、用户事件 和 断言 很好地交互:例如,即使元素在断言之间被重新渲染,Vitest 也会自动重试该元素直到断言成功。
该包暴露了两个入口点:vitest-browser-vue 和 vitest-browser-vue/pure。它们暴露相同的 API,但 pure 入口点不会添加一个在下一次测试开始前移除组件的处理程序。
render
export function render(
component: Component,
options?: ComponentRenderOptions,
): RenderResult & PromiseLike<RenderResult>render 函数会记录一个 vue.render 追踪标记,可在 追踪视图 中看到。
WARNING
render 的同步用法已弃用,并将在下一个主要版本中移除。请始终 await 结果:
const screen = render(Component)
const screen = await render(Component) 选项
render 函数支持来自 @vue/test-utils 的所有 mount 选项(除了 attachTo - 请使用 container 代替)。除此之外,还有 container 和 baseElement。
container
默认情况下,Vitest 会创建一个 div,将其附加到 document.body,并在那里渲染你的组件。如果你提供自己的 HTMLElement 容器,它不会被自动附加 —— 你需要在 render 之前调用 document.body.appendChild(container)。
例如,如果你正在对 tbody 元素进行单元测试,它不能是 div 的子元素。在这种情况下,你可以指定一个 table 作为渲染容器。
const table = document.createElement('table')
const { container } = await render(TableBody, {
props,
// ⚠️ 在渲染前手动将元素附加到 `body`
container: document.body.appendChild(table),
})baseElement
如果指定了 container,则默认为该值,否则默认为 document.body。它用作查询的基础元素,以及在使用 debug() 时打印的内容。
渲染结果
除了文档化的返回值外,render 函数还返回相对于 baseElement 的所有可用 定位器,包括 自定义的。
const screen = await render(TableBody, { props })
await screen.getByRole('link', { name: 'Expand' }).click()container
渲染你的 Vue 组件的包含 DOM 节点。这是一个普通的 DOM 节点,所以从技术上讲,你可以调用 container.querySelector 等来检查子元素。
DANGER
如果你发现自己使用 container 来查询渲染的元素,那么你应该重新考虑!定位器 旨在对你测试的组件将要进行的更改更具弹性。避免使用 container 来查询元素!
baseElement
你的 Vue 组件在 container 中渲染的包含 DOM 节点。如果你在 render 的选项中没有指定 baseElement,它将默认为 document.body。
当你想要测试的组件在容器 div 之外渲染某些内容时,这很有用,例如,当你想要对直接在 body 中渲染 HTML 的 portal 组件进行快照测试时。
TIP
render 返回的查询会查找 baseElement,所以你可以使用查询来测试你的 portal 组件而无需 baseElement。
locator
你的 container 的 定位器。它对于仅限定于你的组件的查询很有用,或者将其传递给其他断言:
import { render } from 'vitest-browser-vue'
const { locator } = await render(NumberDisplay, {
props: { number: 2 }
})
await locator.getByRole('button').click()
await expect.element(locator).toHaveTextContent('Hello World')debug
function debug(
el?: HTMLElement | HTMLElement[] | Locator | Locator[],
maxLength?: number,
options?: PrettyDOMOptions,
): void此方法是 console.log(prettyDOM(baseElement)) 的快捷方式。它会将容器或指定元素的 DOM 内容打印到控制台。
rerender
function rerender(props: Partial<Props>): void & PromiseLike<void>同样会在 追踪视图 中记录一个 vue.rerender 追踪标记。
最好测试正在执行属性更新的组件,以确保属性被正确更新,从而避免在测试中依赖实现细节。也就是说,如果你更喜欢在测试中更新已渲染组件的属性,此函数可用于更新已渲染组件的属性。
WARNING
rerender 的同步用法已弃用,并将在下一个主要版本中移除。请始终 await 结果。
import { render } from 'vitest-browser-vue'
const { rerender } = await render(NumberDisplay, { props: { number: 1 } })
// 使用不同的属性重新渲染相同的组件
await rerender({ number: 2 })unmount
function unmount(): void & PromiseLike<void>这将导致渲染的组件被卸载。同样会在 追踪视图 中记录一个 vue.unmount 追踪标记。这对于测试当你的组件从页面移除时会发生什么很有用(例如测试你是否留下了导致内存泄漏的事件处理程序)。
WARNING
unmount 的同步用法已弃用,并将在下一个主要版本中移除。请始终 await 结果。
emitted
function emitted<T = unknown>(): Record<string, T[]>
function emitted<T = unknown[]>(eventName: string): undefined | T[]返回组件发出的事件。
WARNING
发出的值是未直接暴露给用户的实现细节,所以最好使用 定位器 来测试你的发出值如何改变显示的内容。
cleanup
export function cleanup(): void移除所有使用 render 渲染的组件。
扩展查询
要扩展 locator 查询,请参阅 "Custom Locators"。例如,要使 render 返回一个新的自定义 locator,请使用 locators.extend API 定义它:
import { locators } from 'vitest/browser'
import { render } from 'vitest-browser-vue'
locators.extend({
getByArticleTitle(title) {
return `[data-title="${title}"]`
},
})
const screen = await render(Component)
await expect.element(
screen.getByArticleTitle('Hello World')
).toBeVisible()配置
你可以通过将属性赋值给 config 导出项来配置 Vue Test Utils 选项(在 vitest-browser-vue 和 vitest-browser-vue/pure 中均可用):
import { config } from 'vitest-browser-vue/pure'
config.global.stubs.CustomComponent = {
template: '<div></div>',
}