I moved from Jest to Vitest in less than 3 hours
I’ve read about the multiple benefits of Vitest, such as speed, ease of transitioning from Jest, and no need for a complex Typescript configuration. So, I calculated that a migration of my test stack could be done in less than 6 hours, and it only took me 3 hours. To be honest, it could have been even less. It all depends on your coding speed, the complexity of the project, and the code organization.
🛠️ My Current Stack
This is my current stack; you can see every plugin in the project’s repository (before the upgrade). But the main ones are:
- Gatsby + Typescript over Node 18
- React Test Utils
- ESLint + Prettier
⚙️ Setup and creating your config file
Wondering what to do first? Install Vitest!
But if you want to use React Test Utils, work with React, and add code coverage, install the following libraries as well.
If you’re wondering why
@vitest/coverage-c8is the coverage report tool that Vitest uses by default, follow the instructions from Vitest if you want to change to Instanbul.
Since we are going to work with global definitions for Vitest, add the following piece of code to your
After installing dependencies, create a
vitest.config.ts in the root of your project
I’ve added some options to that config:
react()function in the plugins section adds support for React syntax understanding.
globalsproperty sets common testing functions (e.g.
expect) as globals.
environmentis set to
jsdom. This adds support for querying the DOM when working with
./vitest-setup.ts. We’ll cover this file in depth later.
includepart adds a regex of formats and filenames that will be picked up from the test command. I’ve added support for
coveragespecifies the output format of the coverage tool.
The setup file is where we can specify some actions, before all tests are run. Here I’ve added the connection between the Testing Library and Vitest.
After every test, we keep cleaning the results of generating the React components (
♻️ Updating Mocks
If you have extensive use of Jest Mocks in your project, it can delay your migration more than expected. Vitest offers easy compatibility with Jest’s created Mocks, and here are some quick tips that I used (or discovered) while performing the migration. I always recommend that you refer to their official documentation.
Replace jest with vi
vi.fn() commonly. In the next file of my project,
__mocks__/gatsby-background-image.ts, check how to replace its content.
Replace requireActual with importActual
Let’s check my file
__mocks__/gatsby.ts . Also, check the
Before using any Mock, add a reference of it
What if I want to use my
__mocks__/gatsby.ts showed above? Import it before the tests, or according your test cases.
If you need to use multiple mocks, here is how.
Mocking only before every test
Do you want to have autocompletion in Typescript for mocks created only for a certain file? Check how I add autocomplete support to my mocks.
Autocomplete will start once you finish typing
(useStaticQuery as Mock) .
Spyes changes?, use vi.spyOn
⏬ Updating NPM commands
Vitest commands are ran in
watch mode by default. Use the
run option to avoid leaving them running.
I created alternated commands that I can execute in Github Actions. Check my
🔨 Github Actions
Unfortunately, the plugin that I used to create a report of my coverage is not compatible with Vitest. I hope in the future I will be able to find a similar one, as I have no time to create a fork and modify it.
In Github Actions, this is how I keep running and validating my tests.
🗑️ Removing Jest references
For my portfolio, I no longer needed the following libraries:
- Additionally, I removed three Jest configuration files from my root.
🏎️ Running tests speed comparison
For 74 tests that I have when I’m writing this post, the difference is more than 1 second, having Vitest as a winner. It doesn’t seem like much, but when your tests start growing, the gap will increase, of course.
Here is a comparison about the times that it took to run the tests, using the same quantity of tests.
Since we are talking about development dependencies and a small project. Using Vitest for this case is a no brain. Increased test running speed, Typescript configuration out of the box and support from Jetbrains and Vscode.
However, if you have a big project in Jest, dependent from a huge list of dependencies. My answer is NO, you don’t need to move to Vitest, the effort could be more double or thrice than you thought. Consider small progress, start moving less risky tests by sprints, milestones.
You can check my full PR for my portfolio clicking this link.