Unit Testing Setup
Ionic requires a few additional steps to set up unit tests. If you are using an Ionic starter project, Vitest, React Testing Library, and jest-dom are already installed and src/setupTests.ts is already configured; you only need to initialize Ionic React as described below.
Install Vitest
Vitest runs the tests. It uses jsdom to provide a browser-like environment for the components.
npm install --save-dev vitest jsdom
Then configure Vitest in vite.config.ts to use jsdom and load src/setupTests.ts before the tests run:
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
setupFiles: './src/setupTests.ts',
include: ['src/**/*.test.{ts,tsx}'],
},
});
Install React Testing Library
React Testing Library is a set of utilities that make it easier to test React components. It's used to interact with components and test their behavior.
npm install --save-dev @testing-library/react @testing-library/dom @testing-library/jest-dom
To simulate user interactions with user-event, install it as well. It is not included in Ionic starter projects:
npm install --save-dev @testing-library/user-event
Initialize Ionic React
Ionic React requires the setupIonicReact function to be called before any tests are run. Failing to do so will result in mode-based classes and platform behaviors not being applied to your components.
In src/setupTests.ts, add the following code:
// Adds jest-dom's DOM matchers (toBeInTheDocument, toHaveTextContent, ...) to Vitest's expect.
import '@testing-library/jest-dom/vitest';
+ import { setupIonicReact } from '@ionic/react';
import { cleanup } from '@testing-library/react';
import { afterEach } from 'vitest';
+ setupIonicReact();
+
// Testing Library only cleans up automatically when Vitest globals are enabled.
afterEach(() => {
cleanup();
});
// jsdom doesn't implement matchMedia, which Ionic uses for platform and dark mode checks.
window.matchMedia =
window.matchMedia ||
function (query: string): MediaQueryList {
return {
matches: false,
media: query,
onchange: null,
addListener: () => undefined,
removeListener: () => undefined,
addEventListener: () => undefined,
removeEventListener: () => undefined,
dispatchEvent: () => false,
};
};