Skip to content

Commit ac47520

Browse files
committed
docs: update the documentation of the tests
1 parent 82b2129 commit ac47520

File tree

7 files changed

+122
-691
lines changed

7 files changed

+122
-691
lines changed

docs/testing/converting-old-tests.md

Lines changed: 0 additions & 33 deletions
This file was deleted.
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
---
2-
title: Real-world component testing
2+
title: Cypress component testing
33
category: Testing
4-
order: 5
4+
order: 3
55
---
66

7-
# Real-world component testing
7+
# Cypress component testing
88

99
Sometimes unit test behaviour doesn't match how our components work in the browser (e.g. no ResizeObserver)
1010
InstUI uses [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/overview) for these cases. These are located at `instructure-ui/cypress/component/`.
@@ -28,7 +28,7 @@ Cypress tests usually have a structure like this:
2828
type: code
2929
---
3030
import React from 'react'
31-
import { ComponentToTest } from '../../packages/ui'
31+
import { ComponentToTest } from '@instructure/ui'
3232
import '../support/component'
3333

3434
describe('<ComponentToTest/>', () => {

docs/testing/testing-components.md

Lines changed: 0 additions & 46 deletions
This file was deleted.

docs/testing/testing-overview.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
title: Testing
3+
category: Testing
4+
order: 1
5+
---
6+
7+
## Testing
8+
9+
This page provides an overview of the testing strategies we use to ensure the quality and stability of our components. We use a combination of modern tools to support our testing needs. Each tool serves a different purpose in our testing pyramid, from unit-level validations to full-blown visual and behavioral regression tests.
10+
11+
### Technologies Used:
12+
13+
#### Vitest + React Testing Library:
14+
15+
These tools are our primary stack for writing component-level unit tests. They are lightweight and fast. [Vitest](https://vitest.dev/guide/) is one of the fastest modern testing framework. It offers a Jest-like API and runs in a Node.js environment, making it ideal for testing individual components and functions in isolation. Paired with [React Testing Library](https://testing-library.com/docs/react-testing-library/intro), Vitest encourages accessible and maintainable test practices by querying elements the way users interact with them. It's best suited for testing component logic, rendering conditions, and props/state changes without needing a full browser environment.
16+
17+
#### Cypress Component Testing:
18+
19+
[Cypress Component Testing](https://docs.cypress.io/app/component-testing/get-started) allows you to mount individual components in a real browser environment for precise interaction testing. Unlike traditional unit tests, it renders with full CSS and browser APIs, offering more realistic behavior. This makes it ideal for testing user interactions like clicks, keyboard navigation, focus traps, and animations. While a bit heavier than Vitest, it provides greate visibility and debugging capabilities for complex UI logic.
20+
21+
#### Chromatic Visual Regression Testing with Cypress:
22+
23+
We use [Cypress](https://docs.cypress.io/app/tooling/visual-testing) end-to-end tests to generate structured layouts and capture screenshots of components. [Chromatic](https://www.chromatic.com/docs/diff-inspector/) handles the visual diffing and review process. It's especially effective for catching layout shifts, styling regressions, or broken UI elements that don’t trigger functional test failures. Tests are run after changes are pushed, comparing the new screenshots to a baseline stored from a previously verified state. When differences are detected, the test fails and provides side-by-side diffs for easy review. This type of testing is particularly valuable for pixel-perfect components, design systems, or any feature with strict visual requirements.
24+
25+
#### Cypress Behavioral Regression Testing:
26+
27+
[Cypress Behavioral Regression Testing](https://docs.cypress.io/app/end-to-end-testing/writing-your-first-end-to-end-test) focuses on simulating realistic user flows across complex components or pages to ensure key behaviors remain stable. These tests often replicate critical workflows like navigation, and keyboard interactions. They are useful after feature changes or refactors, as they verify that the components still behaves correctly from the user’s perspective. Since the tests run in a real browser, they provide visibility into full-stack behavior, including browser APIs. These more complex end-to-end style tests are helps catch integration issues or regressions that unit and visual tests may overlook.

docs/testing/ui-test-utils.md

Lines changed: 0 additions & 145 deletions
This file was deleted.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
---
2+
title: Vitest component testing
3+
category: Testing
4+
order: 2
5+
---
6+
7+
## Vitest component testing
8+
9+
[Vitest](https://vitest.dev/guide/) is our fastest tool for in-memory testing of components and logic in a Node.js environment. We pair it with [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) to validate behavior, rendering, and edge cases—all without requiring a real browser.
10+
11+
### Running Vitest
12+
13+
Vitest can be run from the project root with the following command. It's configured in our CI pipeline so pushing a branch to remote runs these tests automatically.
14+
15+
```
16+
npm run test:vitest
17+
```
18+
19+
### Creating new tests
20+
21+
Current tests can be found next to the component source code in the `__tests__` subfolder. New tests should be added there.
22+
23+
Vitest tests usually have a structure like this:
24+
25+
```js
26+
---
27+
type: code
28+
---
29+
import { render, screen } from '@testing-library/react'
30+
import { vi } from 'vitest'
31+
32+
import '@testing-library/jest-dom'
33+
import ComponentToTest from '../index'
34+
35+
describe('<ComponentToTest/>', () => {
36+
it('works as intended...', () => {
37+
const onClickMock = vi.fn()
38+
render(<ComponentToTest onClick={onClickMock}/>)
39+
// rest of the test comes here
40+
})
41+
})
42+
```
43+
44+
### Example
45+
46+
The `ui-avatar` tests can be found [here](https://github.com/instructure/instructure-ui/tree/master/packages/ui-avatar/src/Avatar/__tests__).
47+
48+
### Debugging tests
49+
50+
If you need to debug a test in your IDE or print extra info, you can use:
51+
52+
```
53+
console.log('Debug info')
54+
```
55+
56+
To inspect the rendered DOM and current test state, you can also use:
57+
58+
```
59+
screen.debug()
60+
```
61+
62+
### Simulating Real User Interactions
63+
64+
While fireEvent from React Testing Library works for basic interaction simulation, we use @testing-library/user-event for more realistic and accessible user interaction testing.
65+
[userEvent](https://testing-library.com/docs/user-event/intro/) is a companion library for Testing Library that provides more advanced simulation of browser interactions than the built-in fireEvent method.
66+
While fireEvent dispatches single DOM events, userEvent can fire multiple events and do additional checks along the way, making your tests closer to actual user experience.
67+
68+
Use it in the following way:
69+
70+
```js
71+
---
72+
type: code
73+
---
74+
import { render, screen } from '@testing-library/react'
75+
import { vi } from 'vitest'
76+
77+
import '@testing-library/jest-dom'
78+
import userEvent from '@testing-library/user-event'
79+
import ComponentToTest from '../index'
80+
81+
describe('<ComponentToTest/>', () => {
82+
it('works as intended...', async () => {
83+
const onKeyDownMock = vi.fn()
84+
render(<ComponentToTest onKeyDown={onKeyDownMock}/>)
85+
86+
const input = screen.getByTestId('input')
87+
await userEvent.type(input, 'foo bar{enter}')
88+
// rest of the test comes here
89+
})
90+
})
91+
```

0 commit comments

Comments
 (0)