Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/aygunbyr/react-testing-tutorial
React Testing Tutorial from Codevolution
https://github.com/aygunbyr/react-testing-tutorial
jest msw react-testing-library
Last synced: about 1 month ago
JSON representation
React Testing Tutorial from Codevolution
- Host: GitHub
- URL: https://github.com/aygunbyr/react-testing-tutorial
- Owner: aygunbyr
- Created: 2023-09-05T16:42:21.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2023-09-16T21:26:42.000Z (over 1 year ago)
- Last Synced: 2023-09-17T03:43:14.830Z (over 1 year ago)
- Topics: jest, msw, react-testing-library
- Language: TypeScript
- Homepage:
- Size: 751 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# React Testing Tutorial Notes
These notes have been taken while following React Testing Tutorial. I have been just taking notes that I need. It may not be helpful for you.
## Useful Links
[React Testing Tutorial - YouTube](https://www.youtube.com/playlist?list=PLC3y8-rFHvwirqe1KHFCHJ0RqNuN61SJd)
[Expect - Jest](https://jestjs.io/docs/expect)
[ByRole | Testing Library](https://testing-library.com/docs/queries/byrole/)
[Document conformance requirements for use of ARIA attributes in HTML](https://www.w3.org/TR/html-aria/#docconformance)
[Cheatsheet | Testing Library](https://testing-library.com/docs/react-testing-library/cheatsheet/)
[Testing Playground Chrome Extension](https://chrome.google.com/webstore/detail/testing-playground/hejbmebodbijjdhflfknehhcgaklhano)
[Custom Render](https://testing-library.com/docs/react-testing-library/setup#custom-render)
[MSW – Seamless API mocking library for browser and Node | Mock Service Worker](https://mswjs.io/)
[Install - Getting Started - Mock Service Worker Docs](https://mswjs.io/docs/getting-started/install)
[Node - Getting Started - Mock Service Worker Docs](https://mswjs.io/docs/getting-started/integrate/node)
## What to test ?
- Test component renders
- Test component renders with props
- Test component renders in different states
- Test component reacts to events## What not to test ?
- Implementation details
- Third party code
- Code that is not important from a user point of view## Priority Order for Queries
"Your test should resemble how users interact with your code (component, page, etc.) as much as possible"
1. getByRole (you can filter elements by name)
2. getByLabelText (good for form fields)
3. getByPlaceholderText
4. getByText (for non-interactive elements; div, span, paragraphs)
5. getByDisplayValue (current value of a form element)
6. getByAltText (image, area, input)
7. getByTitle
8. getByTestId## queryBy and queryAllBy
### queryBy
- Returns the matching node for a query, and return null if no elements match
- Useful for asserting an element that is not present
- Throws an error if more than one match is found### queryAllBy
- Returns an array of all matching nodes for a query, and return an empty array if no elements match
## findBy and findAllBy
### findBy
- Returns a Promise which resolves when an element is found which matches the given query
- The promise is rejected if no element is found or if more than one element is found after a default timeout of 1000ms### findAllBy
- Returns a promise which resolves to an array of elements when any elements are found which match the given query
- The promise is rejected if no elements are found after a default timeout of 1000ms## User Interactions
A click using a mouse or a keypress using a keyboard
Software has to respond to such interactions
Test should ensure the interactions are handled as expected
### user-event
A companion library for Testing Library that simulates user interactions by dispatching the events that would happen if the interaction took place in a browser
It is the recommended way to test user interactions with RTL
### fireEvent vs user-event
fireEvent is a method from RTL which is used to dispatch DOM events
user-event simulates full interactions, which may fire multiple events and do additional checks along the way
For example, we can dispatch the change event on an input field using fireEvent
When a user types into a text box, the element has to be focused, and then keyboard and input events are fired and the selection and value on the element are manipulated as they type
user-event allows you to describe a user interaction instead of a concrete event. It adds visibility and intractability checks along the way and manipulates the DOM just like a user interaction in the browser would. It factors in that the browser e.g. wouldn't let a user click a hidden element or type in a disabled text box
### Update the package @testing-library/user-event
CRA installs user-event but needs upgrading
userEvent.setup() was introduced in v14.
```
npm install @testing-library/user-event@latest
```### Pointer Interactions
#### Convenience APIs (much easier to read and write)
- click()
- dblClick()
- tripleClick()
- hover()
- unhover()#### Pointer APIs
- pointer({keys: '[MouseLeft]'})
- pointer({keys: '[MouseLeft][Mouseright]'})
- pointer('[MouseLeft][Mouseright]')
- pointer('[MouseLeft>]') (without releasing button)
- pointer('[/MouseLeft]') (releasing previously pressed button)### Keyboard Interactions
#### Utility API
- clear()
```js
test('clear', async () => {
render();
await userEvent.clear(screen.getByRole('textbox'));
expect(screen.getByRole('textbox')).toHaveValue('');
});
```- selectOptions()
```js
test('selectOptions', async () => {
render(
A
B
C
,
);
await userEvent.selectOptions(screen.getByRole('listbox'), ['1', 'C']);
expect(screen.getByRole('option', { name: 'A' }).selected).toBe(true);
expect(screen.getByRole('option', { name: 'B' }).selected).toBe(false);
expect(screen.getByRole('option', { name: 'C' }).selected).toBe(true);
});
```- deselectOptions()
```js
test('deselectOptions', async () => {
render(
A
B
C
,
);
await userEvent.deselectOptions(screen.getByRole('listbox'), '2');
expect(screen.getByText('B').selected).toBe(false);
});
```- upload()
```js
test('upload file', async () => {
render(
,
Upload file:
);
const file = new File(['hello'], 'hello.png', { type: 'image/png}' });
const input = screen.getByLabelText(/upload file/i);
await userEvent.upload(input, file);
expect(input.files[0].toBe(file));
expect(input.files.item(0)).toBe(file);
expect(input.files).toHaveLength(1);
});
```#### Clipboard APIs
- copy()
- cut()
- paste()#### Keyboard API
- keyboard('foo') // translates to: f, o, o
- keyboard('{Shift>}A{/Shift}') // translates to: Shift(down), A, Shift(up)## Static analysis testing
Process of verifying that your code meets certain expectations without actually running it
- Ensure consistent style and formatting
- Check for common mistakes and possible bugs
- Limit the complexity of code and
- Verify type consistencyAll types of tests run the code and then compare the outcome against known expected outputs to see if everything works OK
Static testing analyses aspects such as readability, consistency, error handling, type checking and alignment with best practises
Testing checks if your code works or not, whereas static analysis checks if it is written well or not
### Static analysis testing tools
- TypeScript
- ESlint
- Prettier
- Husky
- lint-staged## Prettier
Prettier is a opinionated code formatter that ensures that all outputted code conforms to a consistent style
```
npm install --save-dev --save-exact prettier
```### eslint-config-prettier
Installation
```
npm install --save-dev eslint-config-prettier
```## Husky
Husky is a tool that helps improve your commits and more
### husky-init
```
npx husky-init && npm install
```## lint-staged
Run linters (and formatters) against staged git files
Installation
```
npm install --save-dev lint-staged # requires further setup
```Run tests before each push, it creates pre-push file:
```
npx husky add .husky/pre-push "npm test -- --watchAll=false"
```