-
Notifications
You must be signed in to change notification settings - Fork 3.2k
docs(react): writing tests with testing-library #2861
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
Merged
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
d99ad24
docs(react): writing tests with testing-library
sean-perkins 5ab70e6
docs: installing react testing library
sean-perkins a000173
docs: testing a modal presented from useIonModal
sean-perkins d426393
docs: remove unneeded async
sean-perkins e2b1891
docs: rework intro sections
sean-perkins 7f2fd80
chore: restructure sections
sean-perkins 26d97a8
chore: doc updates
sean-perkins 7568760
Update docs/react/testing/unit-testing/setup.md
sean-perkins 1b23cda
Update docs/react/testing/introduction.md
sean-perkins 71214cf
Update docs/react/testing/unit-testing/setup.md
sean-perkins 2e6afe3
Update docs/react/testing/introduction.md
sean-perkins 7024a23
Update docs/react/testing/introduction.md
sean-perkins 74b905d
chore: remove additional resources section
sean-perkins d916fd7
chore: add react scripts section
sean-perkins 1690215
chore: simplify
sean-perkins c3ca12a
chore: remove vitest
sean-perkins 788c28e
chore: fix import statements
sean-perkins 0871187
chore: jsx syntax
sean-perkins 2b50a69
chore: update description
sean-perkins 3afcf59
chore: adjust types of tests
sean-perkins abf4fdf
chore: update based on vitest
sean-perkins 66ab966
chore: prettier formatting
sean-perkins 6d66871
chore: add redirect for old url to new
sean-perkins 7a18197
chore: note for ionic starters
sean-perkins File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
--- | ||
sidebar_label: Introduction | ||
title: Ionic React Testing Introduction | ||
description: Learn how to test an Ionic React application. This document provides an overview of how to test an application built with @ionic/react. | ||
--- | ||
|
||
# Testing Ionic React | ||
|
||
This document provides an overview of how to test an application built with `@ionic/react`. It covers the basics of testing with React, as well as the specific tools and libraries developers can use to test their applications. | ||
|
||
## Introduction | ||
|
||
Testing is an important part of the development process, and it helps to ensure that an application is working as intended. In `@ionic/react`, testing is done using a combination of tools and libraries, including Jest, React Testing Library, Playwright or Cypress. | ||
|
||
## Types of Tests | ||
|
||
There are two types of tests that can be written: | ||
|
||
**Unit Tests**: Unit tests are used to test individual functions and components in isolation. [Jest](https://jestjs.io) and [React Testing Library](https://testing-library.com) are commonly used for unit testing. | ||
|
||
**Integration Tests**: Integration tests are used to test how different components work together. [Cypress](https://www.cypress.io) or [Playwright](https://playwright.dev) are commonly used for integration testing. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
--- | ||
sidebar_label: Best Practices | ||
--- | ||
|
||
# Best Practices | ||
|
||
## IonApp is required for test templates | ||
|
||
In your test template when rendering with React Testing Library, you must wrap your component with an `IonApp` component. This is required for the component to be rendered correctly. | ||
|
||
```tsx title="Example.test.tsx" | ||
import { IonApp } from '@ionic/react'; | ||
import { render } from "@testing-library/react"; | ||
|
||
import Example from './Example'; | ||
|
||
test('example', () => { | ||
render( | ||
<IonApp> | ||
<Example /> | ||
</IonApp> | ||
); | ||
... | ||
}); | ||
``` | ||
|
||
## Use `user-event` for user interactions | ||
|
||
React Testing Library recommends using the `user-event` library for simulating user interactions. This library provides a more realistic simulation of user interactions than the `fireEvent` function provided by React Testing Library. | ||
|
||
```tsx title="Example.test.tsx" | ||
import { IonApp } from '@ionic/react'; | ||
import { render } from '@testing-library/react'; | ||
sean-perkins marked this conversation as resolved.
Show resolved
Hide resolved
|
||
import userEvent from '@testing-library/user-event'; | ||
|
||
import Example from './Example'; | ||
|
||
test('example', async () => { | ||
const user = userEvent.setup(); | ||
|
||
render( | ||
<IonApp> | ||
<Example /> | ||
</IonApp> | ||
); | ||
|
||
await user.click(screen.getByRole('button', { name: /click me!/i })); | ||
}); | ||
``` | ||
|
||
For more information on `user-event`, see the [user-event documentation](https://testing-library.com/docs/user-event/intro/). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
--- | ||
sidebar_label: Examples | ||
title: Ionic React Testing Examples | ||
description: Learn how to test an Ionic React application. This document provides examples of how to test different types of components. | ||
--- | ||
|
||
# Examples | ||
|
||
## Testing a modal presented from a trigger | ||
|
||
This example shows how to test a modal that is presented from a trigger. The modal is presented when the user clicks a button. | ||
|
||
### Example component | ||
|
||
```tsx title="src/Example.tsx" | ||
import { IonButton, IonModal } from '@ionic/react'; | ||
|
||
export default function Example() { | ||
return ( | ||
<> | ||
<IonButton id="open-modal">Open</IonButton> | ||
<IonModal trigger="open-modal">Modal content</IonModal> | ||
</> | ||
); | ||
} | ||
``` | ||
|
||
### Testing the modal | ||
|
||
```tsx title="src/Example.test.tsx" | ||
import { IonApp } from '@ionic/react'; | ||
import { fireEvent, render, screen, waitFor } from '@testing-library/react'; | ||
|
||
import Example from './Example'; | ||
|
||
test('button presents a modal when clicked', async () => { | ||
render( | ||
<IonApp> | ||
<Example /> | ||
</IonApp> | ||
); | ||
// Simulate a click on the button | ||
fireEvent.click(screen.getByText('Open')); | ||
// Wait for the modal to be presented | ||
await waitFor(() => { | ||
// Assert that the modal is present | ||
expect(screen.getByText('Modal content')).toBeInTheDocument(); | ||
}); | ||
}); | ||
``` | ||
|
||
## Testing a modal presented from useIonModal | ||
|
||
This example shows how to test a modal that is presented using the `useIonModal` hook. The modal is presented when the user clicks a button. | ||
|
||
### Example component | ||
|
||
```tsx title="src/Example.tsx" | ||
import { IonContent, useIonModal, IonHeader, IonToolbar, IonTitle, IonButton, IonPage } from '@ionic/react'; | ||
|
||
const ModalContent: React.FC = () => { | ||
return ( | ||
<IonContent> | ||
<div>Modal Content</div> | ||
</IonContent> | ||
); | ||
}; | ||
|
||
const Example: React.FC = () => { | ||
const [present] = useIonModal(ModalContent); | ||
return ( | ||
<IonPage> | ||
<IonHeader> | ||
<IonToolbar> | ||
<IonTitle>Blank</IonTitle> | ||
</IonToolbar> | ||
</IonHeader> | ||
<IonContent fullscreen={true}> | ||
<IonButton expand="block" className="ion-margin" onClick={() => present()}> | ||
Open | ||
</IonButton> | ||
</IonContent> | ||
</IonPage> | ||
); | ||
}; | ||
|
||
export default Example; | ||
``` | ||
|
||
### Testing the modal | ||
|
||
```tsx title="src/Example.test.tsx" | ||
import { IonApp } from '@ionic/react'; | ||
import { fireEvent, render, screen, waitFor } from '@testing-library/react'; | ||
|
||
import Example from './Example'; | ||
|
||
test('should present ModalContent when button is clicked', async () => { | ||
render( | ||
<IonApp> | ||
<Example /> | ||
</IonApp> | ||
); | ||
// Simulate a click on the button | ||
fireEvent.click(screen.getByText('Open')); | ||
// Wait for the modal to be presented | ||
await waitFor(() => { | ||
// Assert that the modal is present | ||
expect(screen.getByText('Modal Content')).toBeInTheDocument(); | ||
}); | ||
}); | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
--- | ||
sidebar_label: Setup | ||
title: Ionic React Unit Testing Setup | ||
description: Learn how to set up unit tests for an Ionic React application. | ||
--- | ||
|
||
# Unit Testing Setup | ||
|
||
Ionic requires a few additional steps to set up unit tests. If you are using an Ionic starter project, these steps have already been completed for you. | ||
|
||
### Install React Testing Library | ||
|
||
React Testing Library is a set of utilities that make it easier to test React components. It's used to interact with components and test their behavior. | ||
|
||
```bash | ||
npm install --save-dev @testing-library/react @testing-library/jest-dom @testing-library/user-event | ||
``` | ||
|
||
### Initialize Ionic React | ||
|
||
Ionic React requires the `setupIonicReact` function to be called before any tests are run. Failing to do so will result in mode-based classes and platform behaviors not being applied to your components. | ||
|
||
In `src/setupTest.ts`, add the following code: | ||
liamdebeasi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```diff | ||
import '@testing-library/jest-dom/extend-expect'; | ||
|
||
+ import { setupIonicReact } from '@ionic/react'; | ||
|
||
+ setupIonicReact(); | ||
|
||
// Mock matchmedia | ||
window.matchMedia = window.matchMedia || function () { | ||
return { | ||
matches: false, | ||
addListener: function () { }, | ||
removeListener: function () { } | ||
}; | ||
}; | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.