Skip to content

Commit 3830698

Browse files
committed
Update testing docs to use RNTL 14
1 parent 3b3859e commit 3830698

2 files changed

Lines changed: 92 additions & 72 deletions

File tree

versioned_docs/version-7.x/testing.md

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,11 @@ Fake timers replace real implementation of the native timer functions (e.g. `set
127127
Often, component state is updated after an animation completes. To avoid getting an error in such cases, wrap `jest.runAllTimers()` in `act`:
128128

129129
```js
130-
import { act } from 'react-test-renderer';
130+
import { act } from '@testing-library/react-native';
131131

132132
// ...
133133

134-
act(() => jest.runAllTimers());
134+
await act(() => jest.runAllTimers());
135135
```
136136

137137
See the examples below for more details on how to use fake timers in tests involving navigation.
@@ -148,11 +148,11 @@ expect(screen.getByText('Settings screen')).toBeVisible();
148148

149149
This is in contrast to the `toBeOnTheScreen` matcher, which checks if the element is rendered in the component tree. This matcher is not recommended when writing tests involving navigation.
150150

151-
By default, the queries from React Native Testing Library (e.g. `getByRole`, `getByText`, `getByLabelText` etc.) [only return visible elements](https://callstack.github.io/react-native-testing-library/docs/api/queries#includehiddenelements-option). So you don't need to do anything special. However, if you're using a different library for your tests, you'll need to account for this behavior.
151+
By default, the queries from React Native Testing Library (e.g. `getByRole`, `getByText`, `getByLabelText` etc.) [only return visible elements](https://oss.callstack.com/react-native-testing-library/docs/api/queries#includehiddenelements-option). So you don't need to do anything special. However, if you're using a different library for your tests, you'll need to account for this behavior.
152152

153153
## Example tests
154154

155-
We recommend using [React Native Testing Library](https://callstack.github.io/react-native-testing-library/) to write your tests.
155+
We recommend using [React Native Testing Library](https://oss.callstack.com/react-native-testing-library/) to write your tests.
156156

157157
In this guide, we will go through some example scenarios and show you how to write tests for them using Jest and React Native Testing Library:
158158

@@ -246,13 +246,13 @@ test('navigates to settings by tab bar button press', async () => {
246246

247247
const Navigation = createStaticNavigation(MyTabs);
248248

249-
render(<Navigation />);
249+
await render(<Navigation />);
250250

251251
const button = screen.getByRole('button', { name: 'Settings, tab, 2 of 2' });
252252

253253
await user.press(button);
254254

255-
act(() => jest.runAllTimers());
255+
await act(() => jest.runAllTimers());
256256

257257
expect(screen.getByText('Settings screen')).toBeVisible();
258258
});
@@ -273,17 +273,19 @@ jest.useFakeTimers();
273273
test('navigates to settings by tab bar button press', async () => {
274274
const user = userEvent.setup();
275275

276-
render(
276+
await render(
277277
<NavigationContainer>
278278
<MyTabs />
279279
</NavigationContainer>
280280
);
281281

282-
const button = screen.getByLabelText('Settings, tab, 2 of 2');
282+
const button = screen.getByRole('button', {
283+
name: 'Settings, tab, 2 of 2',
284+
});
283285

284286
await user.press(button);
285287

286-
act(() => jest.runAllTimers());
288+
await act(() => jest.runAllTimers());
287289

288290
expect(screen.getByText('Settings screen')).toBeVisible();
289291
});
@@ -294,8 +296,8 @@ test('navigates to settings by tab bar button press', async () => {
294296

295297
In the above test, we:
296298

297-
- Render the `MyTabs` navigator within a [NavigationContainer](navigation-container.md) in our test.
298-
- Get the tab bar button using the `getByLabelText` query that matches its accessibility label.
299+
- Render the `MyTabs` navigator using [`createStaticNavigation`](static-configuration.md#createstaticnavigation) for static configuration or a [NavigationContainer](navigation-container.md) for dynamic configuration.
300+
- Get the tab bar button using the `getByRole` query that matches its role and accessible name.
299301
- Press the button using `userEvent.press(button)` to simulate a user interaction.
300302
- Run all timers using `jest.runAllTimers()` to skip animations (e.g. animations in the `Pressable` for the button).
301303
- Assert that the `Settings screen` is visible after the navigation.
@@ -422,11 +424,11 @@ test('shows surprise text after navigating to surprise screen', async () => {
422424

423425
const Navigation = createStaticNavigation(MyStack);
424426

425-
render(<Navigation />);
427+
await render(<Navigation />);
426428

427-
await user.press(screen.getByLabelText('Click here!'));
429+
await user.press(screen.getByRole('button', { name: 'Click here!' }));
428430

429-
act(() => jest.runAllTimers());
431+
await act(() => jest.runAllTimers());
430432

431433
expect(screen.getByText('Surprise!')).toBeVisible();
432434
});
@@ -447,15 +449,15 @@ jest.useFakeTimers();
447449
test('shows surprise text after navigating to surprise screen', async () => {
448450
const user = userEvent.setup();
449451

450-
render(
452+
await render(
451453
<NavigationContainer>
452454
<MyStack />
453455
</NavigationContainer>
454456
);
455457

456-
await user.press(screen.getByLabelText('Click here!'));
458+
await user.press(screen.getByRole('button', { name: 'Click here!' }));
457459

458-
act(() => jest.runAllTimers());
460+
await act(() => jest.runAllTimers());
459461

460462
expect(screen.getByText('Surprise!')).toBeVisible();
461463
});
@@ -466,8 +468,8 @@ test('shows surprise text after navigating to surprise screen', async () => {
466468

467469
In the above test, we:
468470

469-
- Render the `MyStack` navigator within a [NavigationContainer](navigation-container.md) in our test.
470-
- Get the button using the `getByLabelText` query that matches its title.
471+
- Render the `MyStack` navigator using [`createStaticNavigation`](static-configuration.md#createstaticnavigation) for static configuration or a [NavigationContainer](navigation-container.md) for dynamic configuration.
472+
- Get the button using the `getByRole` query that matches its role and accessible name.
471473
- Press the button using `userEvent.press(button)` to simulate a user interaction.
472474
- Run all timers using `jest.runAllTimers()` to skip animations (e.g. navigation animation between screens).
473475
- Assert that the `Surprise!` text is visible after the transition to the Surprise screen is complete.
@@ -696,10 +698,14 @@ test('loads data on Pokemon info screen after focus', async () => {
696698

697699
const Navigation = createStaticNavigation(MyTabs);
698700

699-
render(<Navigation />);
701+
await render(<Navigation />);
700702

701-
const homeTabButton = screen.getByLabelText('Home, tab, 1 of 2');
702-
const pokemonTabButton = screen.getByLabelText('Pokemon, tab, 2 of 2');
703+
const homeTabButton = screen.getByRole('button', {
704+
name: 'Home, tab, 1 of 2',
705+
});
706+
const pokemonTabButton = screen.getByRole('button', {
707+
name: 'Pokemon, tab, 2 of 2',
708+
});
703709

704710
await user.press(pokemonTabButton);
705711

@@ -737,14 +743,18 @@ jest.useFakeTimers();
737743
test('loads data on Pokemon info screen after focus', async () => {
738744
const user = userEvent.setup();
739745

740-
render(
746+
await render(
741747
<NavigationContainer>
742748
<MyTabs />
743749
</NavigationContainer>
744750
);
745751

746-
const homeTabButton = screen.getByLabelText('Home, tab, 1 of 2');
747-
const pokemonTabButton = screen.getByLabelText('Pokemon, tab, 2 of 2');
752+
const homeTabButton = screen.getByRole('button', {
753+
name: 'Home, tab, 1 of 2',
754+
});
755+
const pokemonTabButton = screen.getByRole('button', {
756+
name: 'Pokemon, tab, 2 of 2',
757+
});
748758

749759
await user.press(pokemonTabButton);
750760

@@ -775,7 +785,7 @@ In the above test, we:
775785
- Assert that the `ditto` text is visible after the data is fetched.
776786
- Press the home tab button to navigate to the home screen.
777787
- Run all timers using `jest.runAllTimers()` to skip animations (e.g. animations in the `Pressable` for the button).
778-
- Press the profile tab button to navigate back to the Pokemon screen.
788+
- Press the Pokemon tab button to navigate back to the Pokemon screen.
779789
- Ensure that cached data is shown by asserting that the `Loading...` text is not visible and the `ditto` text is visible.
780790

781791
:::note
@@ -828,12 +838,12 @@ We can use this test navigator in our tests like this:
828838
<TabItem value="static" label="Static" default>
829839

830840
```js title="MyComponent.test.js"
831-
import { act, render, screen } from '@testing-library/react-native';
841+
import { render, screen } from '@testing-library/react-native';
832842
import { createStaticNavigation } from '@react-navigation/native';
833843
import { createTestStackNavigator } from './TestStackNavigator';
834844
import { MyComponent } from './MyComponent';
835845

836-
test('does not show modal when not focused', () => {
846+
test('does not show modal when not focused', async () => {
837847
const TestStack = createTestStackNavigator({
838848
screens: {
839849
A: MyComponent,
@@ -843,7 +853,7 @@ test('does not show modal when not focused', () => {
843853

844854
const Navigation = createStaticNavigation(TestStack);
845855

846-
render(
856+
await render(
847857
<Navigation
848858
initialState={{
849859
routes: [{ name: 'A' }, { name: 'B' }],
@@ -854,7 +864,7 @@ test('does not show modal when not focused', () => {
854864
expect(screen.queryByText('Modal')).not.toBeVisible();
855865
});
856866

857-
test('shows modal when focused', () => {
867+
test('shows modal when focused', async () => {
858868
const TestStack = createTestStackNavigator({
859869
screens: {
860870
A: MyComponent,
@@ -864,7 +874,7 @@ test('shows modal when focused', () => {
864874

865875
const Navigation = createStaticNavigation(TestStack);
866876

867-
render(
877+
await render(
868878
<Navigation
869879
initialState={{
870880
routes: [{ name: 'B' }, { name: 'A' }],
@@ -880,12 +890,12 @@ test('shows modal when focused', () => {
880890
<TabItem value="dynamic" label="Dynamic">
881891

882892
```js title="MyComponent.test.js"
883-
import { act, render, screen } from '@testing-library/react-native';
893+
import { render, screen } from '@testing-library/react-native';
884894
import { NavigationContainer } from '@react-navigation/native';
885895
import { createTestStackNavigator } from './TestStackNavigator';
886896
import { MyComponent } from './MyComponent';
887897

888-
test('does not show modal when not focused', () => {
898+
test('does not show modal when not focused', async () => {
889899
const Stack = createTestStackNavigator();
890900

891901
const TestStack = () => (
@@ -895,7 +905,7 @@ test('does not show modal when not focused', () => {
895905
</Stack.Navigator>
896906
);
897907

898-
render(
908+
await render(
899909
<NavigationContainer
900910
initialState={{
901911
routes: [{ name: 'A' }, { name: 'B' }],
@@ -908,7 +918,7 @@ test('does not show modal when not focused', () => {
908918
expect(screen.queryByText('Modal')).not.toBeVisible();
909919
});
910920

911-
test('shows modal when focused', () => {
921+
test('shows modal when focused', async () => {
912922
const Stack = createTestStackNavigator();
913923

914924
const TestStack = () => (
@@ -918,7 +928,7 @@ test('shows modal when focused', () => {
918928
</Stack.Navigator>
919929
);
920930

921-
render(
931+
await render(
922932
<NavigationContainer
923933
initialState={{
924934
routes: [{ name: 'B' }, { name: 'A' }],

0 commit comments

Comments
 (0)