-
Notifications
You must be signed in to change notification settings - Fork 4.7k
docs: adding information to testing docs #1493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
281cc97
dfbc234
c944c0c
cb1157b
ac3a7fb
5ed22d1
a15b394
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
<script setup lang="ts"> | ||
import { ref } from 'vue'; | ||
const activeId = ref('vtu-api') | ||
|
||
const testingLangs = [ | ||
{ | ||
label: 'Vue Test Utils', | ||
className: 'vtu-api' | ||
}, | ||
{ | ||
label: 'Cypress', | ||
className: 'cypress-api' | ||
}, | ||
{ | ||
label: 'Testing Library', | ||
className: 'testing-library-api' | ||
}, | ||
] | ||
|
||
</script> | ||
|
||
<template> | ||
<div class="testing-code-examples" :class="`prefers-${activeId}`"> | ||
<div class="tabs"> | ||
<div | ||
v-for="lang in testingLangs" | ||
:key="lang.className" | ||
class="tab" | ||
:class="{ active: lang.className === activeId }" | ||
@click="activeId = lang.className" | ||
>{{ lang.label }}</div> | ||
</div> | ||
<div class="code-example"> | ||
<slot/> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<style scoped> | ||
/* TODO: Replace with a VTCodeGroup when available */ | ||
/* Layout */ | ||
.code-examples { | ||
display: flex; | ||
flex-direction: column; | ||
} | ||
|
||
.code-example :slotted([class*=language]) { | ||
margin-top: 0; | ||
border-top-left-radius: 0; | ||
} | ||
|
||
/* Tab Styles */ | ||
.tabs { | ||
display: flex; | ||
} | ||
|
||
.tab { | ||
color: white; | ||
background: #292d3ef0; | ||
border-bottom-color: rgba(255,255,255,0.3); | ||
padding: 6px 24px; | ||
border-width: 2px; | ||
border-style: solid; | ||
border-top: transparent; | ||
border-right: transparent; | ||
border-left: transparent; | ||
cursor: pointer; | ||
transition: border, background-color .2s; | ||
transition-property: border, background-color; | ||
transition-duration: 0.2s, 0.2s; | ||
transition-timing-function: ease, ease; | ||
transition-delay: 0s, 0s; | ||
} | ||
|
||
.tab.active { | ||
background: #292d3e; | ||
border-bottom: 2px solid var(--vt-c-brand); | ||
} | ||
|
||
.tab:first-child { | ||
border-top-left-radius: 8px; | ||
} | ||
|
||
.tab:last-child { | ||
border-top-right-radius: 8px; | ||
} | ||
|
||
/* When the sm media query hits, make sure the | ||
tabs line up with the negative margins of the | ||
code blocks. Should also remove the border radius. | ||
*/ | ||
@media screen and (max-width: 639px) { | ||
.tabs { | ||
margin: 0 -24px; | ||
} | ||
|
||
.tab, .tab:first-child, .tab:last-child { | ||
flex-grow: 1; | ||
text-align: center; | ||
border-radius: 0; | ||
} | ||
} | ||
|
||
:global(.dark .testing-code-examples .tab:not(.active)) { | ||
border-bottom: 2px solid rgba(255,255,255,.2); | ||
background: #2f2f2f; | ||
color: inherit; | ||
} | ||
|
||
:global(.dark .testing-code-examples .tab.active) { | ||
background: var(--vt-c-black-soft); | ||
} | ||
|
||
/* Show/Hide logic for codeblocks */ | ||
:slotted([class$="api"]) { | ||
display: none; | ||
} | ||
|
||
.prefers-cypress-api :slotted(.cypress-api), | ||
.prefers-testing-library-api :slotted(.testing-library-api), | ||
.prefers-vtu-api :slotted(.vtu-api) { | ||
display: block; | ||
} | ||
|
||
</style> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,102 @@ | ||
<script setup> | ||
import TestingApiSwitcher from './TestingApiSwitcher.vue' | ||
</script> | ||
|
||
# Testing | ||
|
||
## Overview | ||
## Why Test? | ||
|
||
Automated tests help you and your team build complex Vue applications quickly and confidently by preventing regressions and encouraging you to break apart your application into testable functions, modules, classes, and components. As with any application, your new Vue app can break in many ways, and it's important that you can catch these issues and fix them before releasing. | ||
|
||
When it comes to building reliable applications, automated tests can play a critical role in an individual or team's ability to build new features, refactor code, and fix bugs with confidence. | ||
In this guide, we'll cover basic terminology and provide our recommendations on which tools to choose for your Vue 3 application. | ||
|
||
In a Vue application, there are different types of concerns that can be covered by automated tests: | ||
There is one Vue-specific section covering composables. See [Testing Composables](#testing-composables) below for more details. | ||
|
||
- **Logic**: verify non-UI rendering logic is implemented correctly. This typically involves application-wide business logic (e.g. state management stores) and utility functions. | ||
## When to Test | ||
|
||
- **Visual**: given certain input props / state, verify that an isolated component or component tree is rendering the correct visual output. | ||
Start testing early! We recommend you begin writing tests as soon as you can. The longer you wait to add tests to your application, the more dependencies your application will have, and the harder it will be to start. | ||
|
||
- **Interaction**: simulate user behavior, such as a click or input, and verify that an isolated component or component tree renders correct, updated output. | ||
## Testing Types | ||
|
||
- **User Flow**: given a sequence of user interactions that are necessary to complete an actual user task, check whether the application as a whole is working as expected. | ||
When designing your Vue application's testing strategy, you should leverage the following testing types: | ||
|
||
For different testing concerns, we need to use different testing techniques: | ||
- **Unit**: Checks that inputs to a given function, class, or composable are producing the expected output or side effects. | ||
- **Component**: Checks that your component mounts, renders, can be interacted with, and behaves as expected. These tests import more code than unit tests, are more complex, and require more time to execute. | ||
- **End-to-end**: Checks features that span multiple pages and make real network requests against your production-built Vue application. These tests often involve standing up a database or other backend. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: I believe we're missing an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah. I thought about that, too. We could write a bullet about integration testing, but I wanted to include the Testing Pyramid graphic if we did that, because integration testing is best defined as a testing type that is relevant to the other testing types. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we do that as a follow-up. I really do want to include the Testing Pyramid to explain how speed/complexity are all relative, but I don't want to rework the sections again right now. |
||
|
||
- **Unit Testing** covers **Logic** tests. | ||
- **Component Testing** covers **Visual** and **Interaction** tests. | ||
- **End-To-End (E2E) Testing** covers **User Flow** tests. | ||
Each testing type plays a role in your application's testing strategy and each will protect you against different types of issues. | ||
|
||
## Overview | ||
|
||
We will briefly discuss what each of these are, how they can be implemented for Vue applications, and provide some general recommendations. | ||
|
||
## Unit Testing | ||
|
||
Unit tests are written to verify that small, isolated units of code are working as expected. They focus on logical correctness that can be easily validated. The most common example of a unit test is testing whether a function returns expected values based on different input arguments. | ||
Unit tests are written to verify that small, isolated units of code are working as expected. A unit test usually covers a single function, class, composable, or module. Unit tests focus on logical correctness and only concern themselves with a small portion of the application's overall functionality. They may mock large parts of your application's environment (e.g. initial state, complex classes, 3rd party modules, and network requests). | ||
|
||
In general, unit tests will catch issues with a function's business logic and logical correctness. | ||
|
||
As mentioned previously, unit testing is typically applied to application-wide business logic or utility functions that do not involve actual UI rendering. These are typically plain JavaScript / TypeScript modules living outside of Vue components. Therefore, writing unit tests in Vue applications does not differ significantly from applications using other frameworks. | ||
Take for example this `increment` function: | ||
|
||
```js | ||
// helpers.js | ||
export function increment (current, max = 10) { | ||
if (current < max) { | ||
return current + 1 | ||
} | ||
return current | ||
} | ||
``` | ||
|
||
Because it's very self-contained, it'll be easy to invoke the increment function and assert that it returns what it's supposed to, so we'll write a Unit Test. | ||
|
||
If any of these assertions fail, it's clear that the issue is contained within the `increment` function. | ||
|
||
```js{4-16} | ||
// helpers.spec.js | ||
import { increment } from './helpers' | ||
|
||
describe('increment', () => { | ||
test('increments the current number by 1', () => { | ||
expect(increment(0, 10)).toBe(1) | ||
}) | ||
|
||
test('does not increment the current number over the max', () => { | ||
expect(increment(10, 10)).toBe(10) | ||
}) | ||
|
||
test('has a default max of 10', () => { | ||
expect(increment(10)).toBe(10) | ||
}) | ||
}) | ||
``` | ||
|
||
As mentioned previously, unit testing is typically applied to self-contained business logic, components, classes, modules, or functions that do not involve UI rendering, network requests, or other environmental concerns. | ||
|
||
These are typically plain JavaScript / TypeScript modules unrelated to Vue. In general, writing unit tests for business logic in Vue applications does not differ significantly from applications using other frameworks. | ||
|
||
There are two instances where you DO unit test Vue-specific features: | ||
|
||
1. Composables | ||
2. Components | ||
|
||
### Composables | ||
|
||
One category of functions specific to Vue applications are [Composables](/guide/reusability/composables.html), which may require special handling during tests. | ||
See [Testing Composables](#testing-composables) below for more details. | ||
|
||
### Unit Testing Components | ||
|
||
A component can be tested in two ways: | ||
|
||
1. Whitebox: Unit Testing | ||
|
||
Tests that are "Whitebox tests" are aware of the implementation details and dependencies of a component. They are focused on **isolating** the component under test. These tests will usually involve mocking some, if not all of your component's children, as well as setting up plugin state and dependencies (e.g. Vuex). | ||
|
||
2. Blackbox: Component Testing | ||
|
||
Tests that are "Blackbox tests" are unaware of the implementation details of a component. These tests mock as little as possible to test the integration of your component and the entire system. They usually render all child components and are considered more of an "integration test". See the [Component Testing recommendations](#component-testing) below. | ||
|
||
### Recommendation | ||
|
||
- [Vitest](https://vitest.dev/) | ||
|
@@ -49,30 +115,113 @@ Vitest is relatively new and is still undergoing rapid development. While it is | |
|
||
## Component Testing | ||
|
||
In Vue applications, components are the main building blocks of the UI. Components are therefore the natural unit of isolation when it comes to visual and interaction tests. From a granularity perspective, component testing sits somewhere above unit testing and can be considered a form of integration testing. In some cases we will be testing a single component, but in other cases we could be testing a tree of components to make sure they are integrated correctly. | ||
In Vue applications, components are the main building blocks of the UI. Components are therefore the natural unit of isolation when it comes to validating your application's behavior. From a granularity perspective, component testing sits somewhere above unit testing and can be considered a form of integration testing. Much of your Vue Application should be covered by a component test and we recommend that each Vue component has its own spec file. | ||
|
||
Component tests should catch issues relating to your component's props, events, slots that it provides, styles, classes, lifecycle hooks, and more. | ||
|
||
Component tests should not mock child components, but instead test the interactions between your component and its children by interacting with the components as a user would. For example, a component test should click on an element like a user would instead of programmatically interacting with the component. | ||
|
||
Component tests should focus on the component's public interfaces rather than internal implementation details. For most components, the public interface is limited to: events emitted, props, and slots. When testing, remember to **test what a component does, not how it does it**. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: I believe we are missing side effects here like dispatching Vuex actions etc There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't believe we should encourage interacting with Vuex actions from within component tests. That's an implementation detail of the component. A litmus test: If you replaced Vuex with Pinia, if the expected behavior of the component is the same, why should your test change? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After reading your other comments: If we're considering a section on "Unit Testing components", then executing Vuex actions makes perfect sense. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @JessicaSachs replace both Vuex/Pinia with calling a side effect like Sentry or external helper. I click the button, I want to make sure my component fires this imported helper, how do I test this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's two solutions: blackbox + whitebox. Blackbox testing: Use Mock Service Worker or cy.intercept() and assert that a network request has been made to your This allows you to catch if your Sentry 3rd party library has broken or you are not using it correctly (maybe the base URL is wrong, etc). It couples you to the "public API" of Sentry and requires you to setup an environment that allows network stubbing, but it does not couple you to the specific files, modules, methods used. Whitebox testing: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a really helpful discourse for me, btw. I hope it's not frustrating for you, because it's very helpful for me to talk through these thought experiments. Thank you. <3 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @JessicaSachs I like the discussions 😅 Sounds like a great summary! I am still not sure whether we should say that component's side effect is a part of the public component interface (because it's an internal part) but I still think we need to test these behaviors no matter what test runner we are using, so they worth a mention. What do you think? |
||
|
||
Component tests should focus on the component's public interfaces rather than internal implementation details. Or, in other words, **test what a component does, not how it does it**. | ||
**DO** | ||
|
||
- **DO** | ||
- For **Visual** logic: assert correct render output based on inputted props and slots. | ||
- For **Behavioral** logic: assert correct render updates or emitted events in response to user input events. | ||
|
||
- For **Visual** tests: assert correct render output based on input props and slots. | ||
- For **Interaction** tests: assert correct render updates or emitted events in response to user input events. | ||
In the below example, we demonstrate a Stepper component that has a DOM element labeled "increment" and can be clicked. We pass a prop called `max` that prevents the Stepper from being incremented past `2`, so if we click the button 3 times, the UI should still say `2`. | ||
|
||
We know nothing about the implementation of Stepper, only that the "input" is the `max` prop and the "output" is the state of the DOM as the user will see it. | ||
|
||
<TestingApiSwitcher> | ||
|
||
<div class="testing-library-api"> | ||
|
||
```js | ||
render(Stepper, { | ||
props: { | ||
max: 1 | ||
} | ||
}) | ||
|
||
const { getByText } = render(Component) | ||
|
||
getByText('0') // Implicit assertion that "0" is within the component | ||
|
||
const button = getByText('increment') | ||
|
||
// Dispatch a click event to our increment button. | ||
await fireEvent.click(button) | ||
|
||
getByText('1') | ||
|
||
await fireEvent.click(button) | ||
``` | ||
|
||
</div> | ||
|
||
<div class="vtu-api"> | ||
|
||
```js | ||
const valueSelector = '[data-testid=stepper-value]' | ||
const buttonSelector = '[data-testid=increment]' | ||
|
||
const wrapper = mount(Stepper, { | ||
props: { | ||
max: 1 | ||
} | ||
}) | ||
|
||
expect(wrapper.find(valueSelector).text()).toContain('0') | ||
|
||
await wrapper.find(buttonSelector).trigger('click') | ||
|
||
expect(wrapper.find(valueSelector).text()).toContain('1') | ||
``` | ||
|
||
</div> | ||
|
||
<div class="cypress-api"> | ||
|
||
```js | ||
const valueSelector = '[data-testid=stepper-value]' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should include "this example is written using Cypress" before we present it, at the very least, since the style is really different from the unit test example (eg the assertions) and that might be a little confusing/jarring. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 100000% if we keep it as a Cy example, we should annotate it. It's disjointed and jarring like "Wtf is this syntax". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would go even further and suggest rewriting the test to Jest/having Jest code as an alternative here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason why this is written in Cy? Considering There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Jest and Vitest are the test runners and aren't really "visible" in this code example. Vitest supports both Mocha and Jasmine matchers. The debate is really: What component mounting strategy are we recommending?Vue Test Utilsconst wrapper = mount(Stepper, {
props: {
max: 10
}
}) Cypressmount(Stepper, {
props: {
max: 10
}
}) Testing Libraryrender(Stepper, {
props: {
max: 10
}
}) What will we recommend for interacting with components? (Vue Test Utils, Testing Library, Cypress)Vue Test Utilsawait wrapper.get('[data-testid=increment]').trigger('click')
expect(wrapper.get('[data-testid=stepper]').text()).toEqual('1') Cypresscy.get('[data-testid=increment]').click()
cy.get('[data-testid=stepper]').should('contain.text', '1') Testing Libraryconst button = screen.getByTestId('increment')
await fireEvent.click(button)
expect(screen.queryByText('1')).toBeTruthy() What assertion library are we recommending? (Jasmine, Mocha, Cypress's wrapped Mocha)Jasmineexpect('whatever').toBeSomething() Chaiexpect('whatever').to.be.something Cypress's Chaicy.get('button').should('be.something') In this PR we recommend Vitest as the test runner for headless components and unit tests, which comes with both Mocha and Jasmine assertions (Jasmine is camel-case, Mocha is dots) and we recommend Cypress for mounting and clicking on headed components. If we don't want users using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
const buttonSelector = '[data-testid=increment]' | ||
|
||
mount(Stepper, { | ||
props: { | ||
max: 1 | ||
} | ||
}) | ||
|
||
cy.get(valueSelector).should('be.visible').and('contain.text', '0') | ||
.get(buttonSelector).click() | ||
.get(valueSelector).should('contain.text', '1') | ||
``` | ||
|
||
</div> | ||
|
||
</TestingApiSwitcher> | ||
|
||
- **DON'T** | ||
|
||
Assert the private state of a component instance or test the private methods of a component. Testing implementation details makes the tests brittle, as they are more likely to break and require updates when the implementation changes. | ||
|
||
The component's ultimate job is rendering the correct DOM output, so tests focusing on the DOM output provide the same level of correctness assurance (if not more) while being more robust and resilient to change. | ||
|
||
If a method needs to be tested, extract it into a standalone utility function and write a dedicated unit test for it. If it cannot be extracted cleanly, it should be tested as a part of an interaction test that invokes it. | ||
Rely exclusively on snapshot tests. Asserting HTML strings does not describe correctness. Write tests with intentionality. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. praise: great point that if often overlooked in tests! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah it drives me nuts, lol. I remember auditing some major component libraries in our ecosystem and all of their tests were a render and a snapshot 😬. |
||
|
||
If a method needs to be tested thoroughly, consider extracting it into a standalone utility function and write a dedicated unit test for it. If it cannot be extracted cleanly, it may be tested as a part of a component, integration, or end-to-end test that covers it. | ||
|
||
### Recommendation | ||
|
||
- [Vitest](https://vitest.dev/) or the other unit testing frameworks mentioned above can be used for component testing by simulating the DOM in Node.js. See [Adding Vitest to a Project](#adding-vitest-to-a-project) for more details. | ||
- [Vitest](https://vitest.dev/) for components or composables that render headlessly. (e.g. the [`useFavicon`](https://vueuse.org/core/useFavicon/#usefavicon) function in VueUse. Components and DOM can be tested using [@testing-library/vue](https://testing-library.com/docs/vue-testing-library/intro). | ||
|
||
- [Cypress Component Testing](https://on.cypress.io/component) for components whose expected behavior depends on properly rendering styles or triggering native DOM events. Can be used with Testing Library via [@testing-library/cypress](https://testing-library.com/docs/cypress-testing-library/intro). | ||
|
||
### Libraries | ||
The main differences between Vitest and browser-based runners are speed and execution context. In short, browser-based runners, like Cypress, can catch issues that node-based runners, like Vitest, cannot (e.g. style issues, real native DOM events, cookies, local storage, and network failures), but browser-based runners are *orders of magnitude slower than Vitest* because they doopen a browser, compile your stylesheets, and more. Cypress is a browser-based runner that supports component testing. Please read [Vitest's comparison page](https://vitest.dev/guide/comparisons.html#cypress) for the latest information comparing Vitest and Cypress. | ||
|
||
Component testing often involves mounting the component being tested in isolation, triggering simulated user input events, and asserting the rendered DOM output. There are dedicated utility libraries that make these tasks simpler. | ||
### Mounting Libraries | ||
|
||
Component testing often involves mounting the component being tested in isolation, triggering simulated user input events, and asserting on the rendered DOM output. There are dedicated utility libraries that make these tasks simpler. | ||
|
||
- [`@testing-library/vue`](https://github.com/testing-library/vue-testing-library) is a Vue testing library focused on testing components without relying on implementation details. Built with accessibility in mind, its approach also makes refactoring a breeze. Its guiding principle is that the more tests resemble the way software is used, the more confidence they can provide. | ||
|
||
|
@@ -82,15 +231,23 @@ We recommend using `@testing-library/vue` for testing components in applications | |
|
||
### Other Options | ||
|
||
- [Cypress](https://www.cypress.io/) is an E2E test solution, but it also supports [Component Testing](https://docs.cypress.io/guides/component-testing/introduction) which can test components in real browsers with a GUI that shows the actual DOM state during tests. | ||
|
||
- [Nightwatch](https://v2.nightwatchjs.org/) is another E2E test runner with Vue Component Testing support. ([Example Project](https://github.com/nightwatchjs-community/todo-vue) in Nightwatch v2) | ||
- [Nightwatch](https://v2.nightwatchjs.org/) is an E2E test runner with Vue Component Testing support. ([Example Project](https://github.com/nightwatchjs-community/todo-vue) in Nightwatch v2) | ||
|
||
## E2E Testing | ||
|
||
While unit tests provide developers with some degree of confidence, unit and component tests are limited in their abilities to provide holistic coverage of an application when deployed to production. As a result, end-to-end (E2E) tests provide coverage on what is arguably the most important aspect of an application: what happens when users actually use your applications. | ||
|
||
In other words, E2E tests validate all of the layers in your application. This not only includes your frontend code, but all associated backend services and infrastructure that are more representative of the environment that your users will be in. By testing how user actions impact your application, E2E tests are often the key to higher confidence in whether an application is functioning properly or not. | ||
End-to-end tests focus on multi-page application behavior that makes network requests against your production-built Vue application. They often involve standing up a database or other backend and may even be run against a live staging environment. | ||
|
||
End-to-end tests will often catch issues with your router, state management library, top-level components (e.g. an App or Layout), public assets, or any request handling. As stated above, they catch critical issues that may be impossible to catch with unit tests or component tests. | ||
|
||
End-to-end tests do not import any of your Vue application's code, but instead rely completely on testing your application by navigating through entire pages in a real browser. | ||
|
||
End-to-end tests validate many of the layers in your application. They can either target your locally built application, or even a live Staging environment. Testing against your Staging environment not only includes your frontend code and static server, but all associated backend services and infrastructure. | ||
|
||
> The more your tests resemble the way your software is used, the more confidence they can give you. - [Kent C. Dodds](https://twitter.com/kentcdodds/status/977018512689455106) - Author of the Testing Library | ||
|
||
By testing how user actions impact your application, E2E tests are often the key to higher confidence in whether an application is functioning properly or not. | ||
|
||
### Choosing an E2E Testing Solution | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: I am not quite sure we should have a separation here between unit and component testing as component tests are considered a part of unit testing.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's two ways to test components:
wrapper
is the subject under test. This is what I'd consider Unit Testing your components. By using Vue Test Utils directly, you're able to perform Unit Testing.The whitebox/unit method of testing components isn't documented or represented in the guide yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still disagree with this definition. VTU allows you to perform proper blackbox testing if you don't assert
wrapper.vm
properties. Hence, the line between component and unit testing is still blurred for me.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you misunderstood me or I misspoke. You are correct.
Blackbox testing: DOM is the subject under test. VTU (but w/o accessing wrapper.vm or major stubbing), VTL (does not let you access internals), Cy (does not let you access internals)
Whitebox testing: Wrapper is the subject under test, DOM is sometimes used. Lots of stubbing. VTU supports whitebox via Shallow Mount. Not possible to perform with Cy or VTL.