Migrate from Jest to Vitest

C.Chambers
Smartbox engineering
5 min readMar 3, 2023

Introduction

On our project we started developing using VueCli, We built the majority of the project with Vuei Cli and Jest with Vuex and Vue3.

Over the course of development, we decided to migrate away from Vue Cli due to a number of reasons.

  1. VuecCli was now no longer the recommended environment for Vue projects
  2. Vuex was now replaced by Pinia as the recommended store management package.
  3. Jest was also replaced by Vitest as the recommended testing suite for Vite builds.

Note: The use of Vuex and jest is still possible on Vite projects, but for us we decided to keep up with the trend and migrate our project to stay evergreen.

Note: This article expects you to be using a project that is based on Vite.
You can read more about how to migrate from Vue CLI to Vite here (coming soon)

Our planning:

  1. Install Vitest
  2. Install happy-dom
  3. Install c8 coverage reporter
  4. Convert tests to Vitest
  5. Run our Tests

Installing Vitest

To install Vitest to our project we will run the following command

npm install -D vitest

Note: Vitest requires Vite >=v3.0.0 and Node >=v14

This will install Vitest to our development dependencies in the package.json.

The next thing we want to do is create a vitest.config.js file in our project's root. Below are the contents of my vitest.config let's take a look.

import { mergeConfig } from 'vite';
import { defineConfig } from 'vitest/config';

export default mergeConfig(
defineConfig({
test: {
globals: true,
environment: 'happy-dom',
exclude: ['**/node_modules/**', '**/tests/e2e/**'],
coverage: {
provider: 'c8',
reporter: ['text', 'json', 'html'],
lines: 100,
functions: 100,
branches: 100,
statements: 100,
exclude: [
'**/src/yourIgnoredFile.js',
],
},
},
}),
);

Let's break this config down:

globals : By default, vitest does not provide global APIs for explicitness. If you prefer to use the APIs globally like Jest, you can pass the --globals option to CLI or add globals: true in the config.

environment: The environment that will be used for testing. The default environment in Vitest is a Node.js environment. If you are building a web application, you can use browser-like environment through either jsdom or happy-dom instead. For this project, we are using happy-dom as it is compatible with the c8 coverage package.

exclude: This is pretty self-explanatory, place the paths of the files you want Vitest to ignore in array format.

coverage: the coverage config is how we will configure our coverage settings, we set the provider to c8 ( which is a package we are going to install later), and then we can configure our coverage levels for lines, functions, branches and statements, setting 100 means that the unit tests must cover 100% of each item, adjust this to suit the status of your project and slowly increase the number to 100. We also have excluded property inside the coverage config this allows you to ignore files from the coverage reports.

Install Happy-Dom

Happy DOM is a JavaScript implementation of a web browser without its graphical user interface. We need to install this as Vitest is a node.js environment so by installing this we can render our tests inside the browser.

npm i -D happy-dom

You should now see happy-dom listed in your package.json, And we have already configured our vitest.config.ts to use it.

Install C8 coverage reporter

Vitest supports Native code coverage via c8

# For c8
npm i -D @vitest/coverage-c8

Now you should see c8 listed in your package.json and we have also already configured this in our vitest.config.js

Configure our Run command to run Vitest

//package.json

"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
"test:unit": "vitest run --coverage",
},

As you can see we call Vitest with the run command and pass in the coverage flag.

Let's Fire this up and see what happens!

Success! well sort of! Now convert our unit test files

Since Vitest is running and is giving us errors we can now start to convert our tests to the new Vitest syntax. Luckily Vitest and jest have very similar syntax.

The easiest way to do this is to use your IDE to find and replace all instances of “jest.” and replace with “vi.”!

That will make your jest mock functions and custom mocks look like this:

const example = jest.fn();
cosnt example = vi.fn();

We don't need to import anything into our test files as the Vitest suite is provided globally just like jest since we configured this in the vitest.config.js file.

This is the longest part and it depends on how big your project is we had quite a lot of files to change which is why I recommend the find and replace feature on your IDE.

Replacing dom classes

In my project tests, I use classes to find elements in components to grab data and use them in tests. To do this we used class names such as “jest-example-test”. We must remember to change these to “vi-example-test” since we are removing jest from our project. This might not apply to you but it's just a reminder to clean up behind you.

Time for the Big finale

Once you have converted all your test files to the new Vitest syntax you can now run your test suite and see if all your tests pass.

// in my case my command is 
npm run test:unit

Job Done

Now your project is using Vitest as its testing suite and you have removed jest from your project. By setting your coverage to 100 in your config you should have lots of unit tests to write with Vitest! Lucky you!

Note: remember to uninstall all devDependencies that reference jest from your package.json

I found Vitest calculated the code coverage of our codebase differently compared to jest this meant I had to spend some more time improving the test coverage back to 100% code coverage.

Thanks for reading this article I hope you found this article useful.

--

--