Efficiently Migrating From Jest to Vitest in a Next.js Project
Vitest offers faster, streamlined testing for modern JavaScript projects. This article explains how to transition from Jest to Vitest, enhancing efficiency.
Join the DZone community and get the full member experience.
Join For FreeVitest is a state-of-the-art testing framework that was created to solve problems encountered with older testing frameworks such as Jest. It's designed to be faster and leaner, with a tidier API, and more importantly, to be more efficient with projects that use modern JavaScript features and toolchains.
Why Was Vitest Invented?
Vitest was created to offer a new spin on testing JavaScript. Light and lightning-fast, it focuses on performance and modern JavaScript features, such as ES modules. Unlike Jest, Vitest is built with Vite, a modern front-end build tool, which means it can exploit ES modules (and other shiny new things) to initialize and run tests much more quickly.
What’s more, if you’re using Vite to power your web project, switching to Vitest is almost absurdly easy (unlike, say, switching from Karma to Jest). Vitest is, in a sense, the promised land toward which all JavaScript testers should be journeying.
What Is Lacking in Jest?
Although Jest provides a complete set of features for testing, its efficiency does tend to wane in several areas:
- Slow startup and execution for large codebases. Jest can be slow to start up and execute tests, particularly in large codebases, because of its need to transform modules and manage heavy configurations.
- The compatibility of Jest with modern tools. To work perfectly with modern tools like Vite and ES modules, Jest needs extra settings. This often means using plugins or adapters. For example, to get TypeScript support, you might use
ts-jest
. - Utilization of resources. Jest consumes a lot of resources, which might be a drawback for CI/CD pipelines. The resource-hungry test runner could lead to longer build times and possibly increase your cloud costs.
Why Should Teams Consider Migrating to Vitest?
In terms of improving development efficiency, there are several reasons we see teams migrating to Vitest:
- TypeScript support right from the start. Teams using Vitest do not need to configure anything extra because TypeScript is supported natively. This can be a big win for teams that use TypeScript frequently.
- Enhanced speed. Development teams can see up to a 50% increase in the speed of their tests' execution. This allows for quicker iterations in the actual development of the product and helps teams be more responsive.
- Simplified configuration. For projects that are using Vite, integration with Vitest is simple. There is no complex rigging or fine-tuning required, and surely much less in terms of both overhead and just plain confusion when working with a setup that is already quite minimal.
- Current development trends. Vitest is constructed with a forward-thinking approach; it not only natively backs cutting-edge JavaScript functionalities, but it also promotes the adoption of software testing practices that are currently regarded as the best.
In this article, I have outlined a method of migrating a Next.js app from Jest to Vitest, accentuating the tactics I have employed to keep things running smoothly and my team's productivity on the upswing.
Initial Setup: Coexisting Jest and Vitest
Our migration strategy starts with the inclusion of Vitest parallel to Jest, enabling a smooth shift of our tests to this new setup without halting our development velocity.
Step 1: Install Vitest
Begin with the transfer of several test files to check the setup. Modify the Jest configuration so that the new Vitest tests are omitted from consideration:
yarn add vitest --dev
Step 2: Configure Vitest
Generate a vite.config.ts file to set up the initial Vitest environment:
import { fileURLToPath, URL } from 'url';
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
setupFiles: './vitest-setup.ts',
environment: 'jsdom',
include: ['tests-vitest/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
coverage: {
reporter: ['lcov', 'text'],
},
outputFile: 'coverage/sonar-report.xml',
},
resolve: {
alias: [{ find: '@/', replacement: fileURLToPath(new URL('./', import.meta.url)) }],
}
});
Step 3: Setup Test Environment
Include vitest-setup.ts
to integrate jest-dom
with Vitest:
import "@testing-library/jest-dom/vitest";
Modify the package.json
to include scripts for running both Jest and Vitest:
"scripts": {
"test": "jest",
"test:vitest": "vitest"
}
Incremental Migration of Test Files
Migrate test files slowly from Jest to Vitest. Move the test files into a separate directory, and then make necessary adjustments to the files.
Step 4: Migrate Initial Test Files
Begin with the transfer of several test files to check the setup. Modify the Jest configuration so that the new Vitest tests are omitted from consideration:
module.exports = {
testMatch: ['<rootDir>/tests/**/?(*.)+(spec|test).[jt]s?(x)'],
}
Step 5: Validate Changes
Make certain that the two testing frameworks operate as they should and that all tests result in a passing status. Adapt your CI pipelines to execute tests from both Jest and Vitest.
Complete Transition to Vitest
After all tests have been verified to run properly under Vitest, start the last stage of getting rid of Jest.
Step 6: Move All Tests to Vitest
Bring together all tests into the main tests directory and revise the Vitest configuration to match.
Step 7: Remove Jest and Associated Configurations
Uninstalling Jest and taking out any configuration files associated with it.
Conclusion
Gradually switching to Vitest enabled us to enhance the efficiency of our testing framework and avoid placing the team in a situation where they might be overwhelmed or in a CI/CD setup where things could easily become convoluted.
Overall, we have found that Vitest gives us a slight increase in execution speed — around 50% — while also being, completely, a TypeScript solution.
Opinions expressed by DZone contributors are their own.
Comments