Increased development speed brought about by Vite native testing environment
Jest has been the mainstream for front-end testing for many years, but its setup complexity and overhead were issues. By combining “Vitest” and “React Testing Library”, which share Vite settings, you can get an extremely fast testing environment.
We have summarized practical principles for building test suites that are highly maintainable and hard to break.
Principle: Test “user behavior” not “implementation details”
Directly testing a component’s internal state results in brittle tests that break with every refactoring. The basic idea is to verify the behavior of the screen as it appears to the user.
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { LoginForm } from './LoginForm';
test('入力からログイン完了までのフローを検証', async () => {
const user = userEvent.setup();
render(<LoginForm />);
await user.type(screen.getByLabelText('メールアドレス'), 'test@example.com');
await user.click(screen.getByRole('button', { name: 'ログイン' }));
expect(await screen.findByText('ようこそ')).toBeInTheDocument();
});
Pitfalls in asynchronous updates: proper use of query functions
getBy*: Synchronous validation that the element “exists now”. Immediate error if not present.findBy*: Wait for elements that are “asynchronously displayed with a delay” such as API acquisition (returns a Promise).queryBy*: Used to assert that the element “does not exist on the screen” (returns null).
Parallelization points to reduce CI execution time
Vitest uses thread parallel execution by default. For tests that involve DOM manipulation, properly reset mocks in afterEach to maintain independence for each test case, maximize the number of parallel tests, and reduce CI costs.

