Vue 51: Testing Components
easy⏱ 5 mincoursevue
What a real test looks like
A typical Vue component test (Vitest + @testing-library/vue, or @vue/test-utils) mounts the component in a headless DOM, interacts with it like a user would, and asserts on the result. It runs in Node via a test runner - not in this browser sandbox - but the mental model translates directly.
// TodoItem.spec.js
import { render, fireEvent, screen } from '@testing-library/vue';
import TodoItem from './TodoItem.vue';
test('toggles done state on click', async () => {
render(TodoItem, { props: { label: 'Learn Vue testing' } });
const button = screen.getByRole('button');
expect(button).toHaveTextContent('[ ]');
await fireEvent.click(button);
expect(button).toHaveTextContent('[x]');
});
No test runner here - a hand-rolled one instead
There's no Vitest process available in a zero-install browser sandbox. Below, a real Vue component is mounted live, and a hand-rolled 'test runner' panel drives it exactly the way a real test would - click, then assert - logging PASS/FAIL just like a real test report would.
Test behavior, not implementation
Notice the assertions read the text a user would actually see ('[ ]' / '[x]'), not the component's internal state (vm.done). Internals can change in a refactor; the behavior visible to whoever uses the app shouldn't - that's why tests are written this way.