I moved from Jest to Vitest in less than 3 hours
š¤ Why?
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
- Jest
- 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-c8
is the coverage report tool that Vitest uses by default, follow the instructions from Vitest if you want to change to Instanbul.
Typescript file
Since we are going to work with global definitions for Vitest, add the following piece of code to your tsconfig.json
file.
vitest.config.ts
After installing dependencies, create a vitest.config.ts
in the root of your project
Iāve added some options to that config:
- The
react()
function in the plugins section adds support for React syntax understanding. - The
globals
property sets common testing functions (e.g.describe
,it
,expect
) as globals. -
environment
is set tojsdom
. This adds support for querying the DOM when working withreact-test-utils
. - The
setupFiles
property references./vitest-setup.ts
. Weāll cover this file in depth later. - The
include
part adds a regex of formats and filenames that will be picked up from the test command. Iāve added support formjs
andcjs
, which are future Javascript module syntaxes. -
coverage
specifies the output format of the coverage tool.
vitest-setup.ts
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 (afterEach
).
ā»ļø 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
Example: Use 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 await
usage
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 package.json
šØ 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:
-
@types/jest
-
babel-jest
-
jest
-
ts-jest
- 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.
āļø Conclusion
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.