Vue Test Utils
Vue Test Utils (znane także jako @vue/test-utils) to oficjalny zestaw narzędzi do testowania komponentów w frameworku Vue.js. Biblioteka zapewnia API ułatwiające renderowanie, symulowanie zdarzeń i asercje w testach jednostkowych oraz integracyjnych, a jej celem jest uproszczenie procesu weryfikacji zachowania komponentów UI.
Historia
Projekt powstał w 2016 roku jako odpowiedź na rosnącą popularność testów w ekosystemie JavaScript i potrzebę spójnego narzędzia dedykowanego Vue.js. Pierwsza stabilna wersja v1.x została wydana w 2017, a w 2019 pojawiła się wersja v2.x przystosowana do Vue 3. Najnowsza majorowa wersja, v3.x, została opublikowana w 2022 i wprowadziła pełną obsługę TypeScriptu oraz integrację z Jest i Mocha.
Główne cele i założenia
- Umożliwienie testowania komponentów w izolacji (shallow rendering) oraz w pełnym kontekście (mount).
- Zapewnienie API przyjaznego zarówno dla programistów preferujących Jest, jak i Mocha oraz Chai.
- Wsparcie dla nowoczesnych funkcji języka ECMAScript 6 oraz modułów bundlujących (Webpack, Vite).
- Łatwe podłączanie do Node.js i środowisk CI/CD.
Podstawowe pojęcia
- shallowMount
- Funkcja renderująca komponent z zamockowanymi dziećmi, co przyspiesza testy i eliminuje zależności.
- mount
- Pełne renderowanie komponentu wraz z wszystkimi podkomponentami, umożliwiające testowanie interakcji pomiędzy nimi.
- wrapper
- Obiekt zwrócony przez
shallowMountlubmount, zawierający metody do przeszukiwania drzewa, symulacji zdarzeń i asercji. - stubs
- Mechanizm zastępowania wybranych podkomponentów prostymi atrapy, co pozwala kontrolować zachowanie testowanego komponentu.
- props
- Dane wejściowe przekazywane do komponentu; w testach najczęściej definiuje się je jako obiekt JavaScriptowy.
Podstawowe API
Poniżej przedstawiono najważniejsze metody dostępne w Vue Test Utils:
shallowMount(component, options?)– renderowanie komponentu w trybie płytkim.mount(component, options?)– pełne renderowanie komponentu.wrapper.find(selector)– wyszukiwanie pierwszego elementu pasującego do selektora CSS.wrapper.findAll(selector)– zwraca kolekcję wszystkich pasujących elementów.wrapper.setProps(newProps)– aktualizacja właściwości komponentu podczas testu.wrapper.setData(newData)– aktualizacja lokalnego stanu (data) w komponentach opartych na Options API.wrapper.trigger(event, options?)– symulacja zdarzeń DOM, takich jakclick,inputczykeydown.wrapper.emitted([eventName])– dostęp do zdarzeń emitowanych przy pomocy$emit.wrapper.html()– zwraca dostępny w testach markup komponentu.wrapper.isVisible()– sprawdza, czy element jest widoczny w DOM.
Przykładowe środowisko testowe
Typowa konfiguracja testowa wykorzystuje Jest jako runner oraz Vue.js 3. Poniżej znajduje się minimalny przykład pliku MyButton.spec.js:
// MyButton.spec.js
import { shallowMount } from '@vue/test-utils'
import MyButton from '@/components/MyButton.vue' // ścieżka wewnętrzna projektu
describe('MyButton', () => {
it('renderuje tekst przekazany w props', () => {
const wrapper = shallowMount(MyButton, {
props: { label: 'Kliknij mnie' }
})
expect(wrapper.text()).toBe('Kliknij mnie')
})
it('emituje zdarzenie click po kliknięciu', async () => {
const wrapper = shallowMount(MyButton)
await wrapper.trigger('click')
expect(wrapper.emitted()).toHaveProperty('click')
})
})
Integracja z popularnymi frameworkami testowymi
Choć Vue Test Utils nie narzuca konkretnego runnera, najczęściej stosowane są:
- Jest – szybki, z wbudowaną obsługą pokrycia kodu oraz testów migawkowych.
- Mocha wraz z Chai – elastyczne rozwiązanie, często używane w połączeniu z Karma w starszych projektach.
- Vitest – lekka alternatywa dla Jest, oparta na Vite.
Testowanie komponentów z Composition API
W komponentach wykorzystujących Composition API testy mogą odwoływać się do zwracanych funkcji i reaktywnych obiektów. Przykład:
import { mount } from '@vue/test-utils'
import { useCounter } from '@/composables/useCounter'
const TestComponent = {
template: '',
setup() {
const { count, increment } = useCounter()
return { count, increment }
}
}
test('licznik zwiększa się po kliknięciu', async () => {
const wrapper = mount(TestComponent)
expect(wrapper.text()).toBe('0')
await wrapper.trigger('click')
expect(wrapper.text()).toBe('1')
})
Strategie testowania
W praktyce przyjmuje się kilka podejść:
- Testy jednostkowe – koncentrują się na małych fragmentach logiki (np. pojedyncze metody,
computediwatchers). - Testy integracyjne – sprawdzają współdziałanie kilku komponentów, najczęściej przy użyciu
mounti rzeczywistych podkomponentów. - Testy e2e (Cypress, Playwright) – obejmują cały stos od UI po backend, ale nie korzystają bezpośrednio z Vue Test Utils.
Najczęstsze problemy i ich rozwiązania
- „Cannot read property ‘$emit’ of undefined” – zazwyczaj wynika z niewłaściwego użycia
shallowMountbez podania wymaganych props lub stubów. - Problemy z asynchronicznością – po wywołaniu metod zmieniających stan należy używać
await wrapper.vm.$nextTick()lubawait flushPromises()(pakiet flush-promises). - Style i CSS – przy testach jednostkowych nie ma znaczenia renderowanie styli, ale w testach integracyjnych można dodać
global: { stubs: { transition: false } }aby uniknąć opóźnień związanych z animacjami.
Przyszłość i roadmapa
Na GitHubie projektu (repozytorium wewnętrzne encyklopedii) utrzymywany jest publiczny roadmap, w którym planowane są:
- Rozszerzenie wsparcia dla Vue 2 w wersji legacy.
- Lepsza integracja z frameworkiem Vite i szybkie tryby hot module replacement w testach.
- Rozbudowane typy TypeScript generowane automatycznie.
Powiązane pojęcia
Warto zapoznać się także z następującymi artykułami encyklopedycznymi: