Testing React Applications with Vitest and Testing Library
In this guide, we'll set up a testing environment for React applications using Vitest, Testing Library, and jsdom. By following the steps below, you'll be able to create and run tests for your React components efficiently.
Step 1: Install Required Packages
Begin by installing the necessary testing packages. Run the following command in your project directory:
npm install -D @testing-library/react @testing-library/jest-dom vitest jsdom
Step 2: Modify vite.config.js
Next, configure Vitest by updating the vite.config.js file. Add the test configuration as shown below:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: "jsdom",
},
});
This configuration enables the use of global variables like describe, it, and expect in your test files and sets up the jsdom environment for DOM-related tests.
Step 3: Add Test Script in package.json
To streamline test execution, add a script to your package.json file:
"scripts": {
"test": "vitest"
}
You can now run tests using the command:
npm run test
Step 4: Write Your First Test
Create a new file App.test.jsx in the root of your project or inside a __tests__ folder. Use the following code to test a simple App component:
import { render, screen, fireEvent } from "@testing-library/react";
import { describe, it, expect } from "vitest";
import App from "./App";
describe("App Component", () => {
it("renders main headings and text content", () => {
render(<App />);
// Check if main heading exists
const heading = screen.getByText("Vite + React");
expect(heading).toBeDefined();
// Check if instruction text exists
const editText = screen.getByText(/Edit/i);
const learnMoreText = screen.getByText(/Click on the Vite and React logos to learn more/i);
expect(editText).toBeDefined();
expect(learnMoreText).toBeDefined();
});
it("renders Vite and React logos", () => {
render(<App />);
// Check if both logo images are rendered
const viteLogo = screen.getByAltText("Vite logo");
const reactLogo = screen.getByAltText("React logo");
expect(viteLogo).toBeDefined();
expect(reactLogo).toBeDefined();
// Check if logos are wrapped in correct links
const viteLink = viteLogo.closest("a");
const reactLink = reactLogo.closest("a");
expect(viteLink?.getAttribute("href")).toBe("https://vite.dev");
expect(reactLink?.getAttribute("href")).toBe("https://react.dev");
});
it("counter button works correctly", () => {
render(<App />);
// Find the counter button
const counterButton = screen.getByRole("button");
// Check initial count
expect(counterButton.textContent).toContain("count is 0");
// Click button and check if count increases
fireEvent.click(counterButton);
expect(counterButton.textContent).toContain("count is 1");
// Click again to ensure counter keeps increasing
fireEvent.click(counterButton);
expect(counterButton.textContent).toContain("count is 2");
});
it("logos have correct CSS classes", () => {
render(<App />);
const viteLogo = screen.getByAltText("Vite logo");
const reactLogo = screen.getByAltText("React logo");
expect(viteLogo.className).toContain("logo");
expect(reactLogo.className).toContain("logo");
expect(reactLogo.className).toContain("react");
});
it("links open in new tab", () => {
render(<App />);
const links = screen.getAllByRole("link");
links.forEach((link) => {
expect(link.getAttribute("target")).toBe("_blank");
});
});
});
Step 5: Install VS Code Extension ( Optional )
To enhance your testing workflow, install the Vitest Explorer extension in VS Code. This extension allows you to manage tests both from the Testing view and directly within your test files.
Step 6: Run the Tests
Finally, run the tests using:
npm run test
Vitest will execute your tests and display the results in the terminal.
References
Congratulations! You've successfully set up a testing environment for your React application using Vitest and Testing Library. You can now write robust tests to ensure your components behave as expected.