Skip to content
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

docs(react): writing tests with testing-library #2861

Merged
merged 24 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
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 Mar 28, 2023
5ab70e6
docs: installing react testing library
sean-perkins Mar 29, 2023
a000173
docs: testing a modal presented from useIonModal
sean-perkins Mar 29, 2023
d426393
docs: remove unneeded async
sean-perkins Mar 29, 2023
e2b1891
docs: rework intro sections
sean-perkins Mar 29, 2023
7f2fd80
chore: restructure sections
sean-perkins Mar 31, 2023
26d97a8
chore: doc updates
sean-perkins Apr 5, 2023
7568760
Update docs/react/testing/unit-testing/setup.md
sean-perkins Apr 5, 2023
1b23cda
Update docs/react/testing/introduction.md
sean-perkins Apr 5, 2023
71214cf
Update docs/react/testing/unit-testing/setup.md
sean-perkins Apr 5, 2023
2e6afe3
Update docs/react/testing/introduction.md
sean-perkins Apr 5, 2023
7024a23
Update docs/react/testing/introduction.md
sean-perkins Apr 5, 2023
74b905d
chore: remove additional resources section
sean-perkins Apr 5, 2023
d916fd7
chore: add react scripts section
sean-perkins Apr 5, 2023
1690215
chore: simplify
sean-perkins Apr 5, 2023
c3ca12a
chore: remove vitest
sean-perkins Apr 28, 2023
788c28e
chore: fix import statements
sean-perkins Apr 28, 2023
0871187
chore: jsx syntax
sean-perkins Apr 28, 2023
2b50a69
chore: update description
sean-perkins Apr 28, 2023
3afcf59
chore: adjust types of tests
sean-perkins Apr 28, 2023
abf4fdf
chore: update based on vitest
sean-perkins Sep 21, 2023
66ab966
chore: prettier formatting
sean-perkins Oct 2, 2023
6d66871
chore: add redirect for old url to new
sean-perkins Oct 23, 2023
7a18197
chore: note for ionic starters
sean-perkins Oct 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions docs/react/testing.md

This file was deleted.

21 changes: 21 additions & 0 deletions docs/react/testing/introduction.md
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.
51 changes: 51 additions & 0 deletions docs/react/testing/unit-testing/best-practices.md
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";
sean-perkins marked this conversation as resolved.
Show resolved Hide resolved

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/).
112 changes: 112 additions & 0 deletions docs/react/testing/unit-testing/examples.md
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();
});
});
```
40 changes: 40 additions & 0 deletions docs/react/testing/unit-testing/setup.md
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 () { }
};
};
```
18 changes: 17 additions & 1 deletion sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,23 @@ module.exports = {
'react/pwa',
'react/overlays',
'react/storage',
'react/testing',
{
type: 'category',
label: 'Testing',
items: [
'react/testing/introduction',
{
type: 'category',
label: 'Unit Testing',
collapsed: false,
items: [
'react/testing/unit-testing/setup',
'react/testing/unit-testing/examples',
'react/testing/unit-testing/best-practices',
],
},
],
},
'react/performance',
],
},
Expand Down
3 changes: 2 additions & 1 deletion vercel.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
"source": "/docs/vue/your-first-app/6-deploying-mobile",
"destination": "/docs/vue/your-first-app/deploying-mobile"
},
{ "source": "/docs/vue/your-first-app/7-live-reload", "destination": "/docs/vue/your-first-app/live-reload" }
{ "source": "/docs/vue/your-first-app/7-live-reload", "destination": "/docs/vue/your-first-app/live-reload" },
{ "source": "/docs/react/testing", "destination": "/docs/react/testing/introduction" }
],
"rewrites": [
{ "source": "/docs", "destination": "/" },
Expand Down
Loading