Getting Started with Laravel, Vue3, and Vitest

Emeka Mbah
4 min readJun 18, 2023

This short tutorial will guide you through the process of setting up Vitest for Vue3 within your Laravel Vue3 application, typically located in the resources/js directory.

Vitest
Vitest is a unit test framework built on Vite with an eye for speed and minimal config. Vite is a building tool that is fast to compile with Vue projects and is easy to use.

Why Vitest in Laravel?
Vite is a modern front-end build tool that provides an extremely fast development environment and bundles your code for production. When building applications with Laravel, you will typically use Vite to bundle your application’s CSS and JavaScript files into production-ready assets.

Setting up Vitest in Laravel
Assuming you have set up a Laravel project with Vue, and you are now attempting to test your Vue components using Vitest. Get started with these steps.

Install Dependencies

npm install -D vitest

We also need to install some plugins @vitejs/plugin-vue, @vue/test-utils and jsdom

@vitejs/plugin-vue is a plugin provided by Vite, a build tool for modern web applications. This specific plugin allows you to seamlessly use Vue.js in your Vite projects. With @vitejs/plugin-vue, you can leverage the power of Vue’s component-based development model while benefiting from the fast and efficient development experience provided by Vite

@vue/test-utils is a utility library provided by the Vue.js ecosystem specifically designed for testing Vue components. With @vue/test-utils, you can mount Vue components in a virtual testing environment, simulate user interactions, access and modify component props and data and assert expected behaviors and outcomes.

jsdom is a JavaScript library that virtually implements the Document Object Model (DOM) in Node.js or browser environments. It allows you to create and manipulate a DOM structure, interact with HTML and XML documents, and simulate a browser-like environment within your JavaScript code.

npm install jsdom @vitejs/plugin-vue  @vue/test-utils -D

Next up, head over to your package.json which is located in the root of your Laravel application and the snippet below to the scripts.

"test": "vitest",
"coverage": "vitest run --coverage"

Looks like this:

{
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"test": "vitest",
"coverage": "vitest run --coverage"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.2.3",
"@vue/test-utils": "^2.3.2",
"axios": "^1.1.2",
"jsdom": "^22.1.0",
"laravel-vite-plugin": "^0.7.5",
"vite": "^4.0.0",
"vitest": "^0.32.2"
}
}

Next up, set up the Vitest configuration file.
Create the file vitest.config.ts or vitest.config.js in the root of your Laravel application

import { defineConfig } from "vitest/config";
import Vue from "@vitejs/plugin-vue";
import path from "path";

export default defineConfig({
plugins: [Vue()],
test: {
globals: true,
environment: "jsdom",
},

root: path.resolve(__dirname, './resources/js/tests'),

resolve: {
alias: {
'@' : path.resolve(__dirname, './resources/js')
},
}
});

path.resolve(__dirname, ‘./resources/js/tests’) — We are telling Vitest to look for tests in the directory resources/js/tests

’@’ : path.resolve(__dirname, ‘./resources/js’) — This will enable us import files in our Vitest by using the @ alias

Example
Let’s test a simple component called HelloMedium.vue
We created the component in resources/js/Components/HelloMedium.vue

<script setup>
defineProps({
message: {
type: String,
required: true
}
});
</script>
<template>
<div>{{ message }}</div>
</template>

Let’s create a test for the component
The test file needs to be suffixed with .spec.js or .spec.ts for TypeScript
We created resources/js/tests/Components/hello-medium.spec.js

NB: Having your test scripts inside a directory is not mandatory, just a preference.

import { mount } from "@vue/test-utils";
import HelloMedium from "@/Components/HelloMedium.vue";
import { describe, it, expect } from "vitest";

describe("HelloMedium.vue", () => {

it("can render the message", () => {

const message = "I love the Medium";
const wrapper = mount(HelloMedium, {
props: { message },
});

expect(wrapper.text()).toBe(message);
});
});

So basically, in the test script, we used the Vitest expectations API to assert that our component displays the correct message passed through the component properties. Read more here https://vitest.dev/api/expect.html

Let's run the test

npm test

Conclusions
Testing your Vue components is crucial, and setting up Vitest within your Laravel application is remarkably straightforward. This is because Vite, the default Asset Bundling Node package in Laravel 10, seamlessly integrates with Vitest.

Links
https://vitest.dev/

--

--

Emeka Mbah

I am a seasoned software developer who loves writing code in PHP, Laravel, and Javascript