We found these to be the best packages for testing with Nuxt 3. It takes car of a lot of config you would have to do manually with just Vitest. Especially auto imports.
Just for example – do not use! This is the full setup via defineConfig
and Vite
—
import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import AutoImport from 'unplugin-auto-import/vite'; import Components from 'unplugin-vue-components/vite'; import path from 'path'; export default defineConfig({ plugins: [ vue(), Components({ dirs: ['./components'], // this will auto import everything from within nuxt }), AutoImport({ imports: ['vue', 'vitest', 'pinia'], dirs: ['./components', './composables/**/*', './stores/**/*', './plugins', './config'], dts: true, }), ], resolve: { alias: { '@': path.resolve(__dirname, './'), '~': path.resolve(__dirname, './'), }, }, test: { globals: true, environment: 'jsdom', }, });
Setup
pnpm add -D nuxt-vitest vitest@0.33 happy-dom vitest-environment-nuxt
Newer Vitest releases have a bug so use vitest@0.33
for now.
// Nuxt.config.ts
export default defineNuxtConfig({
// ...
modules: [
'nuxt-vitest'
]
})
// vitest.config.js
import { defineVitestConfig } from 'nuxt-vitest/config';
export default defineVitestConfig({
test: {
environment: 'nuxt',
},
});
Testing a component
Component
// ApiTypeTabsDescription.vue
<template>
<div class="mb-5" data-test-id="text-with-more">
<p class="default-registration-info-text">
{{ applicationInstitutionTabDescription }}
<a class="register-show-more-btn-text" @click="showSeeMoreText = !showSeeMoreText">
{{ moreOrHideText }}
</a>
</p>
<p v-if="showSeeMoreText" class="register-show-more-description">
{{ moreInfoText }}
</p>
</div>
</template>
<script setup lang="ts">
const applicationInstitutionTabDescription =
'Please select tab based on the PSD2 permissions authorised for this software';
const moreInfoText =
'This depends on whether software is authorised to retrieve account data provided by banks and financial institutions (AIS) and/or initiate payments from a user’s account (PIS)';
const showSeeMoreText = ref(false);
const moreOrHideText = computed(() => {
if (showSeeMoreText.value === false) {
return 'More';
} else {
return 'Hide';
}
});
</script>
Test file
// components/__tests__/ApiTypeTabsDescription.spec.ts
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { mount, VueWrapper } from '@vue/test-utils';
import ApiTypeTabsDescription from '~/components/ApiTypeTabsDescription.vue';
let wrapper: VueWrapper<any, any>;
wrapper = mount(ApiTypeTabsDescription, { props: {} });
describe('ApiTypeTabsDescription', () => {
it('Default text exists', async () => {
expect(wrapper.find('[data-test-id="text-with-more"]').exists()).toBe(true);
});
it('More text does not exist', async () => {
expect(wrapper.find('.register-show-more-description').exists()).toBe(false);
});
it('More text is visible', async () => {
const toggle = wrapper.find('.register-show-more-btn-text');
await toggle.trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.find('.register-show-more-description').exists()).toBe(true);
});
it('More text is hidden again', async () => {
const toggle = wrapper.find('.register-show-more-btn-text');
// NB. this is the 2nd click in the mount so it will be false
await toggle.trigger('click');
await wrapper.vm.$nextTick();
expect(wrapper.find('.register-show-more-description').exists()).toBe(false);
});
});
Running the test with watchers
Add
// package.json
"scripts": {
// ...
"test": "vitest"
// ...
Run
pnpm test
Leave a Reply