Add Vitest to a Next app
Adding Vitest to a Next app and writing a simple test
How to add Vitest to an already existing Next app.
Install packages
npm i @testing-library/react @vitejs/plugin-react jsdom vitest --save-devAdd test scripts to your package.json
Inside your package.json add the following to your scripts object
{  // ...rest of package.json  "scripts": {    // ...rest of "scripts"    "test": "vitest run",    "test:dev": "vitest"  }}Create vitest.config.ts
/// <reference types="vitest" />
import { defineConfig } from 'vitest/config'import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/export default defineConfig({  plugins: [react()],  test: {    environment: 'jsdom',  },  // Resolves Next's import alias "@"  resolve: {    alias: {      "@": path.resolve(__dirname, "./"),    },  },})Create __tests__ directory and add Home.test.tsx
Create a __tests__ directory with a new file in it called Home.test.tsx. Vitest (and most other JS-testing libraries) will automatically pick up on and run files in the __tests__ directory. Inside Home.test.tsx put the following:
import { expect, test } from "vitest";import { render, screen, within } from "@testing-library/react";import Home from "@/app/page";
test("Home h1 renders", () => {  render(<Home />);  const main = within(screen.getByRole("main"));  const h1 = main.getByRole("heading", { level: 1, name: /hello test/i });  expect(h1).toBeDefined();});What is the test doing?
In /app/page we have an exported component Home that returns (basically)
<main>  <section>    <h1>Hello test</h1>  </section></main>We want to test that the H1 renders and is readable by its accessible name. Luckily @testing-library/react’s approach to querying the DOM forces a certain amount of accessibility compliance for your tests to pass. Going through the code above we:
- Declare our testfunction with 2 arguments: the test name, and the function to run as the test. In the test function we then…
- Render our <Home />component
- Query the rendered component for the mainelement
- Query the mainelement using getByRole to find aheadingwith a level of1(aka an<h1>), with the accessible name ofhello test. Thenameattribute takes a regex like in this example, but could also just take a plain string of the text
- Declare an expectfunction, where we expect the h1 we queried to exist on the rendered page.
Run the test
In your terminal, run the following command to run our test:
npm run testYou should see the output of our test in your terminal.
Developing more tests
The test:dev command we added to package.json earlier will run vitest in ‘dev’ mode, meaning vitest will watch your tests for changes and re-run them as you save.
npm run test:dev