diff --git a/docs/guides/common-tips.md b/docs/guides/common-tips.md index c95bf183d..44ebf4211 100644 --- a/docs/guides/common-tips.md +++ b/docs/guides/common-tips.md @@ -6,27 +6,29 @@ For UI components, we don't recommend aiming for complete line-based coverage, b Instead, we recommend writing tests that assert your component's public interface, and treat its internals as a black box. A single test case would assert that some input (user interaction or change of props) provided to the component results in the expected output (render result or emitted custom events). -For example, for the `Counter` component which increments a display counter by 1 each time a button is clicked, its test case would simulate the click and assert that the rendered output has increased by 1. The test doesn't care about how the `Counter` increments the value, it only cares about the input and the output. +For example, imagine a `Counter` component which increments a display counter by 1 each time a button is clicked. Its test case would simulate the click and assert that the rendered output has increased by 1. The test should not care about how the `Counter` increments the value – it only cares about the input and the output. The benefit of this approach is that as long as your component's public interface remains the same, your tests will pass no matter how the component's internal implementation changes over time. This topic is discussed with more details in a [great presentation by Matt O'Connell](https://www.youtube.com/watch?v=OIpfWTThrK8). -### Shallow Rendering +### Shallow mounting -In unit tests, we typically want to focus on the component being tested as an isolated unit and avoid indirectly asserting the behavior of its child components. +Sometimes, mounting a whole component with all its all dependencies might become slow or cumbersome. For example, components that contain many child components. -In addition, for components that contain many child components, the entire rendered tree can get really big. Repeatedly rendering all child components could slow down our tests. - -Vue Test Utils allows you to mount a component without rendering its child components (by stubbing them) with the `shallowMount` method: +Vue Test Utils allows you to mount a component without rendering its child components (by stubbing them) with the [`shallowMount`](../api/#shallowmount) method. ```js import { shallowMount } from '@vue/test-utils' +import Component from '../Component.vue' const wrapper = shallowMount(Component) -wrapper.vm // the mounted Vue instance ``` +Like [mount](../api/#mount), it creates a [Wrapper](../api/wrapper) that contains the mounted and rendered Vue component, but with stubbed child components. + +Notice that using `shallowMount` will make the component under testing different from the component you run in your application – some of its parts won't be rendered! This is why it is not the suggested way of testing components unless you face performance issues or need to simplify test arrangements. + ### Lifecycle Hooks
diff --git a/docs/guides/getting-started.md b/docs/guides/getting-started.md index c4f69e49f..cca3cc8be 100644 --- a/docs/guides/getting-started.md +++ b/docs/guides/getting-started.md @@ -2,141 +2,75 @@ -### Setup +### What is Vue Test Utils? -If you already have a project that was created with the [Vue CLI](https://cli.vuejs.org/), you might want to add and configure the [core Jest plugin](https://cli.vuejs.org/core-plugins/unit-jest.html) or the [core Mocha plugin](https://cli.vuejs.org/core-plugins/unit-mocha.html). +Vue Test Utils (VTU) is a set of utility functions aimed to simplify testing Vue.js components. It provides some methods to **mount** and **interact** with Vue components in an isolated manner. -If needed, check out the [Installation guides](../installation/README.md) for further details. - -### Mounting Components - -Vue Test Utils tests Vue components by mounting them in isolation, mocking the necessary inputs (props, injections and user events) and asserting the outputs (render result, emitted custom events). - -Mounted components are returned inside a [Wrapper](../api/wrapper/), which exposes many convenience methods for manipulating, traversing and querying the underlying Vue component instance. - -You can create wrappers using the `mount` method. Let's create a file called `test.js`: +Let's see an example: ```js -// test.js - -// Import the `mount()` method from the test utils -// and the component you want to test +// Import the `mount()` method from Vue Test Utils import { mount } from '@vue/test-utils' -import Counter from './counter' - -// Now mount the component and you have the wrapper -const wrapper = mount(Counter) - -// You can access the actual Vue instance via `wrapper.vm` -const vm = wrapper.vm - -// To inspect the wrapper deeper just log it to the console -// and your adventure with the Vue Test Utils begins -console.log(wrapper) -``` - -### Test rendered HTML output of the component - -Now that we have the wrapper, the first thing we can do is to verify that the rendered HTML output of the component matches what is expected. -```js -import { mount } from '@vue/test-utils' -import Counter from './counter' - -describe('Counter', () => { - // Now mount the component and you have the wrapper - const wrapper = mount(Counter) - - it('renders the correct markup', () => { - expect(wrapper.html()).toContain('0') +// The component to test +const MessageComponent = { + template: '{{ msg }}
', + props: ['msg'] +} + +test('displays message', () => { + // mount() returns a wrapped Vue component we can interact with + const wrapper = mount(MessageComponent, { + propsData: { + msg: 'Hello world' + } }) - // it's also easy to check for the existence of elements - it('has a button', () => { - expect(wrapper.contains('button')).toBe(true) - }) + // Assert the rendered text of the component + expect(wrapper.text()).toContain('Hello world') }) ``` -Now run the tests with `npm test`. You should see the tests passing. +Mounted components are returned inside a [Wrapper](../api/wrapper/), which exposes methods for querying and interacting with the component under testing. ### Simulating User Interaction -Our counter should increment the count when the user clicks the button. To simulate the behavior, we need to first locate the button with `wrapper.find()`, which returns a **wrapper for the button element**. We can then simulate the click by calling `.trigger()` on the button wrapper: +Let's imagine a counter component that increments when user clicks the button: ```js -it('button click should increment the count', () => { - expect(wrapper.vm.count).toBe(0) - const button = wrapper.find('button') - button.trigger('click') - expect(wrapper.vm.count).toBe(1) -}) +const Counter = { + template: ` +Total clicks: {{ count }}
+