Vue.js
Vue.js é um framework acessível, performático e versátil para construir interfaces de usuário web. Você pode testar componentes Vue.js diretamente em um navegador real usando WebdriverIO e seu browser runner.
Configuração
Para configurar o WebdriverIO em seu projeto Vue.js, siga as instruções em nossa documentação de teste de componentes. Certifique-se de selecionar vue
como preset dentro das opções do runner, por exemplo:
// wdio.conf.js
export const config = {
// ...
runner: ['browser', {
preset: 'vue'
}],
// ...
}
Se você já estiver usando o Vite como servidor de desenvolvimento, você também pode reutilizar sua configuração em vite.config.ts
dentro da sua configuração WebdriverIO. Para mais informações, consulte viteConfig
nas opções do runner.
O preset do Vue requer que @vitejs/plugin-vue
esteja instalado. Também recomendamos o uso da Testing Library para renderizar o componente na página de teste. Portanto, você precisará instalar as seguintes dependências adicionais:
- npm
- Yarn
- pnpm
npm install --save-dev @testing-library/vue @vitejs/plugin-vue
yarn add --dev @testing-library/vue @vitejs/plugin-vue
pnpm add --save-dev @testing-library/vue @vitejs/plugin-vue
Você pode então iniciar os testes executando:
npx wdio run ./wdio.conf.js
Escrevendo Testes
Suponha que você tenha o seguinte componente Vue.js:
<template>
<div>
<p>Times clicked: {{ count }}</p>
<button @click="increment">increment</button>
</div>
</template>
<script>
export default {
data: () => ({
count: 0,
}),
methods: {
increment() {
this.count++
},
},
}
</script>
No seu teste, renderize o componente no DOM e execute asserções nele. Recomendamos usar @vue/test-utils
ou @testing-library/vue
para anexar o componente à página de teste. Para interagir com o componente, use os comandos do WebdriverIO, pois eles se comportam de maneira mais próxima às interações reais do usuário, por exemplo:
- @vue/test-utils
- @testing-library/vue
import { $, expect } from '@wdio/globals'
import { mount } from '@vue/test-utils'
import Component from './components/Component.vue'
describe('Vue Component Testing', () => {
it('increments value on click', async () => {
// The render method returns a collection of utilities to query your component.
const wrapper = mount(Component, { attachTo: document.body })
expect(wrapper.text()).toContain('Times clicked: 0')
const button = await $('aria/increment')
// Dispatch a native click event to our button element.
await button.click()
await button.click()
expect(wrapper.text()).toContain('Times clicked: 2')
await expect($('p=Times clicked: 2')).toExist() // same assertion with WebdriverIO
})
})
import { $, expect } from '@wdio/globals'
import { render } from '@testing-library/vue'
import Component from './components/Component.vue'
describe('Vue Component Testing', () => {
it('increments value on click', async () => {
// The render method returns a collection of utilities to query your component.
const { getByText } = render(Component)
// getByText returns the first matching node for the provided text, and
// throws an error if no elements match or if more than one match is found.
getByText('Times clicked: 0')
const button = await $(getByText('increment'))
// Dispatch a native click event to our button element.
await button.click()
await button.click()
getByText('Times clicked: 2') // assert with Testing Library
await expect($('p=Times clicked: 2')).toExist() // assert with WebdriverIO
})
})
Você pode encontrar um exemplo completo de uma suíte de testes de componentes WebdriverIO para Vue.js em nosso repositório de exemplos.
Testando Componentes Assíncronos no Vue3
Se você estiver usando Vue v3 e testando componentes assíncronos como o seguinte:
<script setup>
const res = await fetch(...)
const posts = await res.json()
</script>
<template>
{{ posts }}
</template>
Recomendamos usar @vue/test-utils
e um pequeno wrapper de suspense para renderizar o componente. Infelizmente, @testing-library/vue
ainda não tem suporte para isso. Crie um arquivo helper.ts
com o seguinte conteúdo:
import { mount, type VueWrapper as VueWrapperImport } from '@vue/test-utils'
import { Suspense } from 'vue'
export type VueWrapper = VueWrapperImport<any>
const scheduler = typeof setImmediate === 'function' ? setImmediate : setTimeout
export function flushPromises(): Promise<void> {
return new Promise((resolve) => {
scheduler(resolve, 0)
})
}
export function wrapInSuspense(
component: ReturnType<typeof defineComponent>,
{ props }: { props: object },
): ReturnType<typeof defineComponent> {
return defineComponent({
render() {
return h(
'div',
{ id: 'root' },
h(Suspense, null, {
default() {
return h(component, props)
},
fallback: h('div', 'fallback'),
}),
)
},
})
}
export function renderAsyncComponent(vueComponent: ReturnType<typeof defineComponent>, props: object): VueWrapper{
const component = wrapInSuspense(vueComponent, { props })
return mount(component, { attachTo: document.body })
}
Então importe e teste o componente da seguinte forma:
import { $, expect } from '@wdio/globals'
import { renderAsyncComponent, flushPromises, type VueWrapper } from './helpers.js'
import AsyncComponent from '/components/SomeAsyncComponent.vue'
describe('Testing Async Components', () => {
let wrapper: VueWrapper
it('should display component correctly', async () => {
const props = {}
wrapper = renderAsyncComponent(AsyncComponent, { props })
await flushPromises()
await expect($('...')).toBePresent()
})
afterEach(() => {
wrapper.unmount()
})
})
Testando Componentes Vue no Nuxt
Se você estiver usando o framework web Nuxt, o WebdriverIO ativará automaticamente o recurso de auto-importação e facilitará o teste de seus componentes Vue e páginas Nuxt. No entanto, qualquer módulo Nuxt que você defina em sua configuração e que requer contexto da aplicação Nuxt não pode ser suportado.
Razões para isso:
- WebdriverIO não pode iniciar uma aplicação Nuxt somente em um ambiente de navegador
- Ter testes de componentes que dependem muito do ambiente Nuxt cria complexidade e recomendamos executar esses testes como testes e2e
O WebdriverIO também fornece um serviço para executar testes e2e em aplicações Nuxt, consulte webdriverio-community/wdio-nuxt-service
para obter informações.
Mockando composables internos
Caso seu componente use um composable nativo do Nuxt, como useNuxtData
, o WebdriverIO automaticamente simulará essas funções e permitirá que você modifique seu comportamento ou faça asserções contra elas, por exemplo:
import { mocked } from '@wdio/browser-runner'
// e.g. your component uses calls `useNuxtData` the following way
// `const { data: posts } = useNuxtData('posts')`
// in your test you can assert against it
expect(useNuxtData).toBeCalledWith('posts')
// and change their behavior
mocked(useNuxtData).mockReturnValue({
data: [...]
})
Lidando com composables de terceiros
Todos os módulos de terceiros que podem potencializar seu projeto Nuxt não podem ser automaticamente simulados. Nesses casos, você precisa simulá-los manualmente, por exemplo, se sua aplicação usa o módulo plugin Supabase:
export default defineNuxtConfig({
modules: [
"@nuxtjs/supabase",
// ...
],
// ...
});
e você cria uma instância do Supabase em algum lugar em seus composables, por exemplo:
const superbase = useSupabaseClient()
o teste falhará devido a:
ReferenceError: useSupabaseClient is not defined
Aqui, recomendamos simular todo o módulo que usa a função useSupabaseClient
ou criar uma variável global que simule essa função, por exemplo:
import { fn } from '@wdio/browser-runner'
globalThis.useSupabaseClient = fn().mockReturnValue({})