Vitest does not offer any utility to test React components and React Testing Library is one of the powerful and most used library in the market.
We also need to install a library like jsdom since we're using HTML / DOM.
npm install @testing-library/react jsdom @testing-library/jest-dom -D
Create a new React Component:
components/Hello.tsx
export default function Hello() {
return <div>Hello World</div>
}
And a replace the content of our test (Hello.test.ts
), that we also need to rename now to Hello.test.tsx
:
Don't forget to use the .tsx
extension to support JSX syntax in your tests
components/Hello.test.tsx
import React from 'react';
import { render, screen } from '@testing-library/react';
import Hello from './Hello';
test('render text', () => {
render(<Hello />);
expect(screen.getByText('Hello World')).toBeInTheDocument();
});
And run test :
npm run test
You'll get an error :
ReferenceError: document is not defined
To fix this issue you need to add the support of jsdom
in your vite.config.ts
:
vite.config.ts
/// <reference types="vitest" />
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import checker from 'vite-plugin-checker';
// https://vitejs.dev/config/
export default defineConfig({
// NEW
test: {
globals: true,
environment: 'jsdom', // <==
},
plugins: [
react(),
checker({ typescript: true }),
// You can also disable type checking when running testing with Vitest
// !process.env.VITEST ? checker({ typescript: true }) : undefined,
],
})
But now you'll get another error:
Error: Invalid Chai property: toBeInTheDocument
But we're not using Chai.
toBeInTheDocument
is part of "Testing Library Jest DOM" API that is used to append its assertions in the test setup file.
So now create a setupTests.ts
file in the project root folder (close to tsconfig.json)
):
setupTests.ts
import { expect, afterEach } from 'vitest';
import { cleanup } from '@testing-library/react';
import matchers from '@testing-library/jest-dom/matchers';
// extends Vitest's expect method with methods from react-testing-library
expect.extend(matchers);
// runs a cleanup after each test case (e.g. clearing jsdom)
afterEach(() => {
cleanup();
});
So we just need to update tsconfig.json
and add the reference to the setup test file.
Furthermore we also add the include
property to define which file Vitest should analyze:
vite.config.ts
/// <reference types="vitest" />
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import checker from 'vite-plugin-checker';
// https://vitejs.dev/config/
export default defineConfig({
// NEW
test: {
globals: true,
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], // <==
setupFiles: './setupTests.ts', // <==
},
plugins: [
react(),
checker({ typescript: true }),
],
})
Now you should kill the current process (
CTRL
+
C
) and run tests again: npm run test
.
It should works fine now.
But we may still have a warning on our IDE:
Add @testing-library/jest-dom
types to tsconfig.json
to fix it:
tsconfig.json
"compilerOptions": {
"types": ["vitest/globals", "@testing-library/jest-dom"],
// ...
}
In the next chapter we'll install Vitest UI, a web user interface to run and check your tests.