2 min read

Add unit testing support to a React project using Vite and Typescript

If you want to test your components in a React + Vite project, the best way is using React Testing Library. This allows you to render your component with different props, interact with it and do assertions on the final output.

To get it set up, you first need to install vitest - this will run the actual tests:

npm install -D vitest

Next, you'll need to install React Testing Library. Since the components will be rendered in a Node context, you need to install jsdom, which emulates the browser DOM for test purposes:

npm install -D @testing-library/react @testing-library/jest-dom jsdom

Next, we need to configure how we want vitest to run our tests. We can do that in the vite.config.ts file:

/// <reference types="vitest/config" />
import { defineConfig } from 'vite';  
import react from '@vitejs/plugin-react';

// [https://vitejs.dev/config/](https://vitejs.dev/config/)  
export default defineConfig({  
	plugins: [react()],  
	test: {  
		globals: true,  
		environment: 'jsdom',  
		setupFiles: ['./src/setupTests.ts'],  
	},  
});

globals: true allows us to use describe, test and it statements in our code without having to first import them - great to keep the code concise!

We also linked to a test config file - we need this to configure React Testing Library custom assertions, like expect(...).toBeInTheDocument(). Let's create the file:

// src/setupTests.ts
import * as matchers from '@testing-library/jest-dom/matchers';
import { expect } from 'vitest';

expect.extend(matchers);

All right, now we're almost ready to run our first test - let's add the test script to package.json:

// package.json
{
...
  "scripts": {
    ...
    "test": "vitest"
  },
  ...
}

When creating tests in React, it's common to place them under a __tests__ folder, in the same location as the component we are testing.
Let's create a test for the App component that the Vite boilerplate comes with:

// src/__tests/App.test.tsx

import { render, screen } from "@testing-library/react";
import App from "../App";

describe("App", () => {
  it("renders the demo Vite text", () => {
    render(<App />);

    expect(screen.getByText("Vite + React")).toBeInTheDocument();
  });
});

If we now run npm run test in the console, we'll see our test passes:

But our entire test file is red! Why is that?
Even if we configured globals:true in the Vite config file, Typescript still does not know of that. We need to update the tsconfig.app.json file to also recognise these globals:

{
  "compilerOptions": {
	...
    "types": ["vitest/globals", "@testing-library/jest-dom"]
  },
  ...
}

With this change in place, the red lines are gone and we can write unit tests in our app 💪

Get the React Practice Calendar!

28 days of focused practice of increasing difficulty, going through everything from Fundamentals, Data fetching, Forms and using Intervals in React.

You will also get notified whenever a new challenge is published.