This content originally appeared on DEV Community and was authored by Sandheep Kumar Patro
Let's start with What is Vitest...
Vitest is a modern unit testing framework designed for blazing-fast performance, especially when working with JavaScript projects. It leverages the power of Vite, a lightning-quick bundler, to streamline the testing process.
Key Advantages:
- Exceptional Speed: Vitest boasts exceptional execution times for your tests, thanks to its reliance on Vite's efficient bundling mechanisms. This translates to a significantly smoother development experience, as you won't have to wait long for tests to run after making changes to your code.
-
Seamless Integration with Vite: If you're already using Vite for your project, Vitest integrates flawlessly. It automatically inherits your Vite configuration, including settings for resolving aliases and plugins, eliminating the need for redundant setup. You can also create a dedicated
vitest.config.ts
file for test-specific configurations. -
Familiarity for Jest Users: Coming from Jest, a popular testing framework? Vitest offers a similar syntax, making the transition comfortable. You'll likely find yourself writing tests in a familiar way, leveraging features like
expect
, snapshots, and code coverage. - Modern JavaScript Support: Vitest embraces modern JavaScript features out of the box, providing built-in support for ES modules, TypeScript, and JSX. This aligns perfectly with the current web development landscape.
- Smart Watch Mode: Inspired by Hot Module Replacement (HMR), Vitest's watch mode is incredibly intelligent. It only re-runs tests that are directly affected by your code changes, significantly reducing the time it takes to get feedback.
Installing Vitest: Simple Setup and Next.js 14 Considerations
Vitest boasts a refreshingly straightforward installation process. To get started with basic unit testing, all you need is a single command:
npm install --save-dev vitest
pnpm add -D vitest
yarn add -D vitest
This installs Vitest as a development dependency in your project. With that done, you're ready to write your first tests!
However, if you're working with a Next.js 14 application, there are a few additional considerations to ensure smooth integration with Vitest.
import { coverageConfigDefaults, defineConfig } from "vitest/config";
import react from "@vitejs/plugin-react";
import path from "path";
export default defineConfig({
plugins: [react()],
test: {
environment: "jsdom",
globals: true,
coverage: {
exclude: [
"next.config.mjs",
"middleware.ts",
"auth.config.ts",
"tailwind.config.ts",
"postcss.config.js",
// other files which dont require unit testing
...coverageConfigDefaults.exclude,
],
},
env: { // execute the command `openssl rand -base64 32` in the terminal and use the returned value here
AUTH_SECRET: {YOUR_SECRET},
},
server: {
deps: {
inline: ["next-auth"],
},
},
},
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
});
Here's a detailed explanation of the above Vitest configuration for Next.js 14:
Imports:
coverageConfigDefaults, defineConfig
are imported fromvitest/config
. These provide helper functions for configuring Vitest.react
is imported from@vitejs/plugin-react
. This plugin enables seamless testing of React components within Vitest.path
is imported from the built-in Node.jspath
module. This provides utilities for working with file paths.
Configuration:
plugins: This array specifies plugins to be used by Vitest. Currently, only the
react
plugin is included, enabling React component testing.-
test: This object configures various aspects of test execution:
- environment: Sets the test environment to "jsdom", which provides a simulated browser environment for running your tests.
-
globals: This setting instructs Vitest to automatically make its built-in test utilities (like
describe
,it
,test
,expect
) globally available within your test files. This eliminates the need to explicitly import them, simplifying your test code (also requires some changes intsconfig
file as well. It's mentioned below). -
coverage: This object configures code coverage reporting:
- exclude: This array specifies files to be excluded from code coverage calculations. This includes common Next.js configuration files, middleware, and potentially other files you don't need unit testing for. It also merges with default exclusions provided by Vitest.
env: This object defines environment variables accessible within your tests. You'll need to replace
{YOUR_SECRET}
with an actual secret value (obtained securely, not shown here for security reasons). This is likely used for testing functionalities that rely on environment variables.-
server: This object configures the test server:
-
deps.inline: This array specifies dependencies to be inlined by the test server. Currently, it includes "next-auth". Inlining is a process where Vite integrates the module directly into the test bundle instead of relying on external imports. This approach can be beneficial for several reasons:
-
Compatibility: It helps handle dependencies that might not strictly follow Node.js ESM (ECMAScript Module) specifications.
next-auth
might be an example of such a dependency. By inlining, Vite ensures compatibility within the test environment. -
Performance: Inlining can sometimes improve test execution speed as the test server doesn't need to resolve and load the dependency separately. Including
next-auth
in thedeps.inline
array suggests that this dependency might be crucial for your tests, potentially because it interacts with functionalities you're testing.
-
Compatibility: It helps handle dependencies that might not strictly follow Node.js ESM (ECMAScript Module) specifications.
-
-
resolve: This object configures how Vitest resolves module imports:
-
alias: This object defines an alias // Run the tests
run();for the root of your source code. Here,
@
is mapped to the./src
directory, simplifying imports within your tests.
-
alias: This object defines an alias // Run the tests
run();for the root of your source code. Here,
Also modify the tsconfig\
file to include the following like for getting editor autocomplete support
{
"compilerOptions": {
// ...other options
"types": ["vitest/globals"],
}
}
Writing the very first test case
Unlocking Geometric Insights: Introducing calculateArea()
Embark on a journey into the realm of geometric computations with the latest tool, calculateArea()
. This versatile function empowers you to effortlessly determine the areas of fundamental shapes such as rectangles, squares, and circles. Proceed further into the blog to explore the inner workings of calculateArea()
, accompanied by a suite of meticulously crafted test cases ensuring its accuracy and reliability.
// calculate.ts
// Function to calculate the area of different shapes
export function calculateArea(shape: string, ...args: number[]): number {
switch (shape) {
case 'rectangle':
if (args.length !== 2) {
throw new Error('Invalid number of arguments for rectangle');
}
return args[0] * args[1];
case 'square':
if (args.length !== 1) {
throw new Error('Invalid number of arguments for square');
}
return args[0] * args[0];
case 'circle':
if (args.length !== 1) {
throw new Error('Invalid number of arguments for circle');
}
return Math.PI * args[0] * args[0];
default:
throw new Error('Invalid shape');
}
}
// calculate.spec.ts
// Import the functions to be tested
import { describe, it, assert, run } from 'vitest';
import { calculateArea } from './calculate';
// Define meaningful test suite descriptions
describe('Area Calculation for Geometric Shapes', () => {
// Test Suite 1: Rectangle and Square
describe('Rectangles and Squares', () => {
// Test case 1: Rectangle area calculation
it('should calculate the area of a rectangle', () => {
assert.equal(calculateArea('rectangle', 3, 4), 12);
});
// Test case 2: Square area calculation
it('should calculate the area of a square', () => {
assert.equal(calculateArea('square', 5), 25);
});
// Test case 3: Rectangle area calculation with negative numbers
it('should handle negative numbers for rectangle area calculation', () => {
assert.equal(calculateArea('rectangle', -3, 4), -12);
});
// Test case 4: Square area calculation with zero
it('should calculate the area of a square with zero side length', () => {
assert.equal(calculateArea('square', 0), 0);
});
});
// Test Suite 2: Circle
describe('Circles', () => {
// Test case 1: Circle area calculation
it('should calculate the area of a circle', () => {
assert.approximately(calculateArea('circle', 3), 28.27, 0.01);
});
// Test case 2: Circle area calculation with larger radius
it('should calculate the area of a circle with larger radius', () => {
assert.approximately(calculateArea('circle', 5), 78.54, 0.01);
});
// Test case 3: Circle area calculation with negative radius
it('should throw an error for negative radius in circle area calculation', () => {
assert.throws(() => calculateArea('circle', -3), 'Invalid number of arguments for circle');
});
// Test case 4: Circle area calculation with zero radius
it('should handle zero radius for circle area calculation', () => {
assert.equal(calculateArea('circle', 0), 0);
});
});
});
npm vitest
This content originally appeared on DEV Community and was authored by Sandheep Kumar Patro
Sandheep Kumar Patro | Sciencx (2024-06-20T18:49:44+00:00) 2. Basics of Vitest. Retrieved from https://www.scien.cx/2024/06/20/2-basics-of-vitest/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.