mirror of
https://github.com/callstack/react-native-testing-library.git
synced 2026-09-18 23:09:04 +08:00
502 lines
172 KiB
HTML
502 lines
172 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head><meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Common Mistakes with React Native Testing Library - React Native Testing Library</title>
|
|
<script>{;const saved = localStorage.getItem('rspress-theme-appearance');const preferDark = window.matchMedia('(prefers-color-scheme: dark)').matches;const isDark = !saved || saved === 'auto' ? preferDark : saved === 'dark';document.documentElement.classList.toggle('dark', isDark);document.documentElement.classList.toggle('rp-dark', isDark);document.documentElement.style.colorScheme = isDark ? 'dark' : 'light';}</script>
|
|
<link href="/react-native-testing-library/static/css/styles.89185f7811.css" rel="stylesheet">
|
|
<script defer src="/react-native-testing-library/static/js/styles.68ae892e1a.js"></script>
|
|
<script defer src="/react-native-testing-library/static/js/lib-react.49604bf759.js"></script>
|
|
<script defer src="/react-native-testing-library/static/js/lib-router.a0df4de158.js"></script>
|
|
<script defer src="/react-native-testing-library/static/js/2482.4740a55c68.js"></script>
|
|
<script defer src="/react-native-testing-library/static/js/index.b6e4c985e3.js"></script>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="generator" content="Rspress v2.0.9">
|
|
<meta property="og:url" content="https://oss.callstack.com/react-native-testing-library/">
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:title" content="Common Mistakes with React Native Testing Library - React Native Testing Library">
|
|
<meta property="og:description" content="Note: This guide is adapted from Kent C. Dodds' article "Common mistakes with React Testing Library" for React Native Testing Library v14. The original article focuses on web React, but the principles apply to React Native as well. This adaptation includes React Native-specific examples, async API usage (v14), and ARIA-compatible accessibility attributes. React Native Testing Library guiding principle is: "The more your tests resemble the way your software is used, the more confidence they can give you." This guide outlines some common mistakes people make when using React Native Testing Library and how to avoid them.">
|
|
<link rel="icon" href="/react-native-testing-library/logo-light.png">
|
|
<meta name="description" content="Note: This guide is adapted from Kent C. Dodds' article "Common mistakes with React Testing Library" for React Native Testing Library v14. The original article focuses on web React, but the principles apply to React Native as well. This adaptation includes React Native-specific examples, async API usage (v14), and ARIA-compatible accessibility attributes. React Native Testing Library guiding principle is: "The more your tests resemble the way your software is used, the more confidence they can give you." This guide outlines some common mistakes people make when using React Native Testing Library and how to avoid them."></head>
|
|
|
|
<body>
|
|
<div id="__rspress_root"><link rel="preload" as="image" href="/react-native-testing-library/img/logo-light.svg"/><link rel="preload" as="image" href="/react-native-testing-library/img/logo-dark.svg"/><link rel="preload" as="image" href="/react-native-testing-library/static/image/abstract-atom.4eca0300ff.avif"/><header class="rp-nav"><div class="rp-nav__left"><div class="rp-nav__title"><a href="/react-native-testing-library/" class="rp-nav__title__link rp-link"><div class="rp-nav__title__logo"><img src="/react-native-testing-library/img/logo-light.svg" alt="logo" id="logo" class="rspress-logo rp-nav__title__logo-image rp-nav__title__logo-image--light"/><img src="/react-native-testing-library/img/logo-dark.svg" alt="logo" id="logo" class="rspress-logo rp-nav__title__logo-image rp-nav__title__logo-image--dark"/></div></a></div></div><div class="rp-nav__right"><button class="rp-search-button"><div class="rp-search-button__content"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16" class="rp-search-button__icon"><path fill="#838289" d="M14.667 14.666h-1.333v-1.333h1.332zm-1.333-1.333H12V12h1.333zm-4-1.333H4v-1.334h5.334zM12 12h-1.335v-1.334h1.335zm-8-1.334H2.665V9.333H4zm6.665 0H9.334V9.333h1.332zm-8-1.333H1.335V4h1.333zm9.335 0h-1.335V4h1.335zM4 4H2.665V2.666H4zm6.665 0H9.334V2.666h1.332zM9.334 2.666H4V1.333h5.334z"></path></svg><span class="rp-search-button__word">Search</span></div><div class="rp-search-button__hotkey" style="opacity:0"><span></span><span>K</span></div></button><div class="rp-search-button--mobile"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16"><path fill="#838289" d="M14.667 14.666h-1.333v-1.333h1.332zm-1.333-1.333H12V12h1.333zm-4-1.333H4v-1.334h5.334zM12 12h-1.335v-1.334h1.335zm-8-1.334H2.665V9.333H4zm6.665 0H9.334V9.333h1.332zm-8-1.333H1.335V4h1.333zm9.335 0h-1.335V4h1.335zM4 4H2.665V2.666H4zm6.665 0H9.334V2.666h1.332zM9.334 2.666H4V1.333h5.334z"></path></svg></div><ul class="rp-nav-menu rp-nav-menu--right"><li class="rp-nav-menu__item rp-nav-menu__item--active"><a href="/react-native-testing-library/docs/start/intro" class="rp-nav-menu__item__container rp-link">Docs</a></li><li class="rp-nav-menu__item"><a href="/react-native-testing-library/cookbook/" class="rp-nav-menu__item__container rp-link">Cookbook</a></li><li class="rp-nav-menu__item"><a href="https://github.com/callstack/react-native-testing-library/tree/main/examples" target="_blank" class="rp-nav-menu__item__container rp-link">Examples</a></li></ul><div class="rp-nav__others"><div class="rp-nav-menu__divider"></div><li class="rp-nav-menu__item"><div class="rp-nav-menu__item__container">14.x<svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" viewBox="0 0 12 13" class="rp-nav-menu__item__icon"><path fill="currentColor" d="M6.5 8.5h1v1h-1v1h-1v-1h-1v-1h1v-6h1zm-2 0h-1v-1h1zm4 0h-1v-1h1zm-5-2v1h-1v-1zm6 1h-1v-1h1z"></path></svg></div><ul class="rp-hover-group rp-hover-group--hidden rp-hover-group--center"><li class="rp-hover-group__item" style="padding-left:8px" data-depth="0"><a href="/react-native-testing-library/12.x/docs/guides/common-mistakes" class="rp-hover-group__item__link rp-link" aria-label="12.x">12.x</a></li><li class="rp-hover-group__item" style="padding-left:8px" data-depth="0"><a href="/react-native-testing-library/13.x/docs/guides/common-mistakes" class="rp-hover-group__item__link rp-link" aria-label="13.x">13.x</a></li><li class="rp-hover-group__item rp-hover-group__item--active" style="padding-left:8px" data-depth="0"><a href="/react-native-testing-library/guides/common-mistakes" class="rp-hover-group__item__link rp-link" aria-label="14.x">14.x</a></li></ul></li><div role="button" tabindex="0" class="rspress-nav-appearance"><div class="rp-p-1 rp-border rp-border-solid rp-border-gray-300 rp-text-gray-400 rp-cursor-pointer rp-rounded-md rp-transition-all rp-duration-300 rp-w-7 rp-h-7"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 24 24"><path fill="currentColor" d="M18 22H8v-2h10zM8 20H6v-2h2zm12 0h-2v-2h2zM6 18H4v-2h2zm16 0h-2v-4h-2v-2h2v-2h2zM4 16H2V6h2zm14 0h-6v-2h6zm-6-2h-2v-2h2zm-2-2H8V6h2zM6 6H4V4h2zm8-2h-2v2h-2V4H6V2h8z"></path></svg></div></div><div class="rp-social-links"><a href="https://github.com/callstack/react-native-testing-library" target="_blank" rel="noopener noreferrer" class="rp-social-links__item"><div class="rp-social-links__icon"><div class="rp-social-links__icon"><svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 24 24"><path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></div></div></a><ul class="rp-hover-group rp-hover-group--hidden rp-hover-group--right"></ul></div></div><button aria-label="mobile hamburger" class="rp-nav-hamburger rp-nav-hamburger__sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="#838289" fill-rule="evenodd" d="M1 9h6v6H1zm2 2v2h2v-2zm6-2h6v6H9zm2 2v2h2v-2zm6-2h6v6h-6zm2 2v2h2v-2z" clip-rule="evenodd"></path></svg></button><button aria-label="mobile hamburger" class="rp-nav-hamburger rp-nav-hamburger__md"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="#838289" fill-rule="evenodd" d="M1 9h6v6H1zm2 2v2h2v-2zm6-2h6v6H9zm2 2v2h2v-2zm6-2h6v6h-6zm2 2v2h2v-2z" clip-rule="evenodd"></path></svg><ul class="rp-hover-group rp-hover-group--hidden rp-hover-group--right"><div class="rp-nav-menu__others-mobile__container"><div class="rp-nav-hamburger__md__hover-group"><div class="rp-nav-screen-appearance"><div class="rp-nav-screen-appearance__left">Theme</div><div class="rp-nav-screen-appearance__right"></div></div><li class="rp-nav-menu__item"><div class="rp-nav-menu__item__container">14.x<svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" viewBox="0 0 12 13" class="rp-nav-menu__item__icon"><path fill="currentColor" d="M6.5 8.5h1v1h-1v1h-1v-1h-1v-1h1v-6h1zm-2 0h-1v-1h1zm4 0h-1v-1h1zm-5-2v1h-1v-1zm6 1h-1v-1h1z"></path></svg></div><ul class="rp-hover-group rp-hover-group--hidden rp-hover-group--center"><li class="rp-hover-group__item" style="padding-left:8px" data-depth="0"><a href="/react-native-testing-library/12.x/docs/guides/common-mistakes" class="rp-hover-group__item__link rp-link" aria-label="12.x">12.x</a></li><li class="rp-hover-group__item" style="padding-left:8px" data-depth="0"><a href="/react-native-testing-library/13.x/docs/guides/common-mistakes" class="rp-hover-group__item__link rp-link" aria-label="13.x">13.x</a></li><li class="rp-hover-group__item rp-hover-group__item--active" style="padding-left:8px" data-depth="0"><a href="/react-native-testing-library/guides/common-mistakes" class="rp-hover-group__item__link rp-link" aria-label="14.x">14.x</a></li></ul></li><div class="rp-nav-screen-divider"></div><div class="rp-social-links"><a href="https://github.com/callstack/react-native-testing-library" target="_blank" rel="noopener noreferrer" class="rp-social-links__item"><div class="rp-social-links__icon"><div class="rp-social-links__icon"><svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 24 24"><path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></div></div></a><ul class="rp-hover-group rp-hover-group--hidden rp-hover-group--right"></ul></div></div></div></ul></button></div></header><div class="rp-doc-layout__menu"><div class="rp-sidebar-menu"><button type="button" class="rp-sidebar-menu__left"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="#838289" d="M20 18H4v-2h16zm0-5H4v-2h16zm0-5H4V6h16z"></path></svg><span>Menu</span></button><button type="button" class="rp-sidebar-menu__right"><span class="rp-sidebar-menu__right__text">Contents</span><svg width="14" height="14" class="rp-progress-circle"><circle cx="7" cy="7" r="6" stroke-linecap="round" fill="none" stroke="var(--rp-c-divider-light)" stroke-width="2"></circle><circle cx="7" cy="7" r="6" stroke-linecap="round" fill="none" stroke="var(--rp-c-brand)" stroke-width="2" stroke-dasharray="37.69911184307752" stroke-dashoffset="37.69911184307752" transform="rotate(-90 7 7)" style="transition:stroke-dashoffset 0.3s"></circle></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" fill="none" viewBox="0 0 12 13" class="rp-sidebar-menu__right__icon" style="transform:rotate(0deg);transition:transform 0.2s ease-out"><path fill="#BCBBC2" d="M6.5 4.5h1v-1h-1v-1h-1v1h-1v1h1v6h1zm-2 0h-1v1h1zm4 0h-1v1h1zm-5 2v-1h-1v1zm6-1h-1v1h1z"></path></svg></button></div></div><div class="rp-doc-layout__container"><aside class="rp-doc-layout__sidebar rp-scrollbar"><div class="rp-sidebar-item rp-sidebar-group" style="padding-left:12px" data-depth="0"><div class="rp-sidebar-item__left"><span>Getting started</span></div><div class="rp-sidebar-item__right"><div style="cursor:pointer;transition:transform 0.2s ease-out;transform:rotate(90deg)"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" fill="none" viewBox="0 0 12 13"><path fill="#BCBBC2" d="M6.5 4.5h1v-1h-1v-1h-1v1h-1v1h1v6h1zm-2 0h-1v1h1zm4 0h-1v1h1zm-5 2v-1h-1v1zm6-1h-1v1h1z"></path></svg></div></div></div><div style="display:grid;grid-template-rows:1fr;transition:grid-template-rows 0.2s ease-out"><div style="overflow:hidden"><a href="/react-native-testing-library/docs/start/intro" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Introduction</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/start/quick-start" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Quick Start</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/start/migration-v14" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>v14 Migration</span></div><div class="rp-sidebar-item__right"></div></a></div></div><div class="rp-sidebar-item rp-sidebar-group" style="padding-left:12px" data-depth="0"><div class="rp-sidebar-item__left"><span>API reference</span></div><div class="rp-sidebar-item__right"><div style="cursor:pointer;transition:transform 0.2s ease-out;transform:rotate(90deg)"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" fill="none" viewBox="0 0 12 13"><path fill="#BCBBC2" d="M6.5 4.5h1v-1h-1v-1h-1v1h-1v1h1v6h1zm-2 0h-1v1h1zm4 0h-1v1h1zm-5 2v-1h-1v1zm6-1h-1v1h1z"></path></svg></div></div></div><div style="display:grid;grid-template-rows:1fr;transition:grid-template-rows 0.2s ease-out"><div style="overflow:hidden"><a href="/react-native-testing-library/docs/api/render" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Render function</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/api/screen" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Screen object</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/api/queries" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Queries</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/api/jest-matchers" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Jest Matchers</span></div><div class="rp-sidebar-item__right"></div></a><div class="rp-sidebar-item rp-sidebar-group rp-sidebar-item--group-item" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Triggering events</span></div><div class="rp-sidebar-item__right"><div style="cursor:pointer;transition:transform 0.2s ease-out;transform:rotate(90deg)"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" fill="none" viewBox="0 0 12 13"><path fill="#BCBBC2" d="M6.5 4.5h1v-1h-1v-1h-1v1h-1v1h1v6h1zm-2 0h-1v1h1zm4 0h-1v1h1zm-5 2v-1h-1v1zm6-1h-1v1h1z"></path></svg></div></div></div><div style="display:grid;grid-template-rows:1fr;transition:grid-template-rows 0.2s ease-out"><div style="overflow:hidden"><a href="/react-native-testing-library/docs/api/events/fire-event" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 2 + 12px)" data-depth="2"><div class="rp-sidebar-item__left"><span>Fire Event</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/api/events/user-event" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 2 + 12px)" data-depth="2"><div class="rp-sidebar-item__left"><span>User Event</span></div><div class="rp-sidebar-item__right"></div></a></div></div><div class="rp-sidebar-item rp-sidebar-group rp-sidebar-item--group-item" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Miscellaneous</span></div><div class="rp-sidebar-item__right"><div style="cursor:pointer;transition:transform 0.2s ease-out;transform:rotate(90deg)"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" fill="none" viewBox="0 0 12 13"><path fill="#BCBBC2" d="M6.5 4.5h1v-1h-1v-1h-1v1h-1v1h1v6h1zm-2 0h-1v1h1zm4 0h-1v1h1zm-5 2v-1h-1v1zm6-1h-1v1h1z"></path></svg></div></div></div><div style="display:grid;grid-template-rows:1fr;transition:grid-template-rows 0.2s ease-out"><div style="overflow:hidden"><a href="/react-native-testing-library/docs/api/misc/accessibility" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 2 + 12px)" data-depth="2"><div class="rp-sidebar-item__left"><span>Accessibility</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/api/misc/async" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 2 + 12px)" data-depth="2"><div class="rp-sidebar-item__left"><span>Async utilities</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/api/misc/config" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 2 + 12px)" data-depth="2"><div class="rp-sidebar-item__left"><span>Config</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/api/misc/other" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 2 + 12px)" data-depth="2"><div class="rp-sidebar-item__left"><span>Other</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/api/misc/render-hook" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 2 + 12px)" data-depth="2"><div class="rp-sidebar-item__left"><span>Render Hook</span></div><div class="rp-sidebar-item__right"></div></a></div></div></div></div><div class="rp-sidebar-item rp-sidebar-group" style="padding-left:12px" data-depth="0"><div class="rp-sidebar-item__left"><span>Guides</span></div><div class="rp-sidebar-item__right"><div style="cursor:pointer;transition:transform 0.2s ease-out;transform:rotate(90deg)"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" fill="none" viewBox="0 0 12 13"><path fill="#BCBBC2" d="M6.5 4.5h1v-1h-1v-1h-1v1h-1v1h1v6h1zm-2 0h-1v1h1zm4 0h-1v1h1zm-5 2v-1h-1v1zm6-1h-1v1h1z"></path></svg></div></div></div><div style="display:grid;grid-template-rows:1fr;transition:grid-template-rows 0.2s ease-out"><div style="overflow:hidden"><a href="/react-native-testing-library/docs/guides/how-to-query" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>How to Query</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/guides/common-mistakes" class="rp-sidebar-item rp-sidebar-item--active rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Common Mistakes</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/guides/llm-guidelines" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>LLM Guidelines</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/guides/troubleshooting" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Troubleshooting</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/guides/faq" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>FAQ</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/guides/community-resources" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Community Resources</span></div><div class="rp-sidebar-item__right"></div></a></div></div><div class="rp-sidebar-item rp-sidebar-group" style="padding-left:12px" data-depth="0"><div class="rp-sidebar-item__left"><span>Advanced Guides</span></div><div class="rp-sidebar-item__right"><div style="cursor:pointer;transition:transform 0.2s ease-out;transform:rotate(90deg)"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" fill="none" viewBox="0 0 12 13"><path fill="#BCBBC2" d="M6.5 4.5h1v-1h-1v-1h-1v1h-1v1h1v6h1zm-2 0h-1v1h1zm4 0h-1v1h1zm-5 2v-1h-1v1zm6-1h-1v1h1z"></path></svg></div></div></div><div style="display:grid;grid-template-rows:1fr;transition:grid-template-rows 0.2s ease-out"><div style="overflow:hidden"><a href="/react-native-testing-library/docs/advanced/testing-env" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Testing Environment</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/advanced/third-party-integration" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Third-party Integration</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/docs/advanced/understanding-act" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Understanding Act</span></div><div class="rp-sidebar-item__right"></div></a></div></div></aside><div class="rp-doc-layout__doc"><main class="rp-doc-layout__doc-container"><div class="rp-doc rspress-doc"><!--$--><h1 class="rp-toc-include" id="common-mistakes-with-react-native-testing-library"><a href="#common-mistakes-with-react-native-testing-library" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Common Mistakes with React Native Testing Library<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg></div><span>Copy Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" viewBox="0 0 12 13" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M6.5 8.5h1v1h-1v1h-1v-1h-1v-1h1v-6h1zm-2 0h-1v-1h1zm4 0h-1v-1h1zm-5-2v1h-1v-1zm6 1h-1v-1h1z"></path></svg></button></div>
|
|
<blockquote>
|
|
<p><strong>Note:</strong> This guide is adapted from Kent C. Dodds' article <a href="https://kentcdodds.com/blog/common-mistakes-with-react-testing-library" target="_blank" rel="noopener noreferrer" class="rp-link">"Common mistakes with React Testing Library"</a> for React Native Testing Library v14. The original article focuses on web React, but the principles apply to React Native as well. This adaptation includes React Native-specific examples, async API usage (v14), and ARIA-compatible accessibility attributes.</p>
|
|
</blockquote>
|
|
<p>React Native Testing Library guiding principle is:</p>
|
|
<blockquote>
|
|
<p>"The more your tests resemble the way your software is used, the more confidence they can give you."</p>
|
|
</blockquote>
|
|
<p>This guide outlines some common mistakes people make when using React Native Testing Library and how to avoid them.</p>
|
|
<h2 class="rp-toc-include" id="using-the-wrong-query"><a href="#using-the-wrong-query" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Using the wrong query</h2>
|
|
<span style="color:#a94442;font-weight:bold">Importance: high</span>
|
|
<p>React Native Testing Library provides several query types. Here's the priority order:</p>
|
|
<ol>
|
|
<li>
|
|
<p><strong>Queries that reflect user experience:</strong></p>
|
|
<ul>
|
|
<li><code>getByRole</code> - most accessible</li>
|
|
<li><code>getByLabelText</code> - accessible label</li>
|
|
<li><code>getByPlaceholderText</code> - <code>TextInput</code> placeholder text</li>
|
|
<li><code>getByText</code> - text content</li>
|
|
<li><code>getByDisplayValue</code> - <code>TextInput</code> input value</li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p><strong>Semantic queries:</strong></p>
|
|
<ul>
|
|
<li><code>getByTestId</code> - only if nothing else works</li>
|
|
</ul>
|
|
</li>
|
|
</ol>
|
|
<p>Here's an example of using the right query:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { TextInput</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> View } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> screen } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'finds input by label'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">TextInput</span><span style="color:var(--shiki-token-function)"> aria-label</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"Username"</span><span style="color:var(--shiki-token-function)"> placeholder</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"Enter username"</span><span style="color:var(--shiki-token-function)"> value</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">""</span><span style="color:var(--shiki-foreground)"> /></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Good - uses accessible label</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> input</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.getByLabelText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Username'</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Also good - uses placeholder</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> inputByPlaceholder</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.getByPlaceholderText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Enter username'</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ❌ Bad - uses testID when accessible queries work</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // const input = screen.getByTestId('username-input');</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<h2 class="rp-toc-include" id="not-using-byrole-most-of-the-time"><a href="#not-using-byrole-most-of-the-time" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Not using <code>*ByRole</code> query most of the time</h2>
|
|
<span style="color:#a94442;font-weight:bold">Importance: high</span>
|
|
<p><code>getByRole</code> is the most accessible query and should be your first choice. It queries elements by their semantic role:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { Pressable</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Text</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> TextInput</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> View } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> screen } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'uses role queries'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Pressable</span><span style="color:var(--shiki-token-function)"> role</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"button"</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Submit</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">Pressable</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">TextInput</span><span style="color:var(--shiki-token-function)"> role</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"searchbox"</span><span style="color:var(--shiki-token-function)"> aria-label</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"Search"</span><span style="color:var(--shiki-token-function)"> placeholder</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"Search..."</span><span style="color:var(--shiki-foreground)"> /></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Good - uses role query</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> button</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.getByRole</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'button'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> { name</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> 'Submit'</span><span style="color:var(--shiki-foreground)"> });</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> searchbox</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.getByRole</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'searchbox'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> { name</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> 'Search'</span><span style="color:var(--shiki-foreground)"> });</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(button)</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(searchbox)</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p>Common roles in React Native include:</p>
|
|
<ul>
|
|
<li><code>button</code> - pressable elements</li>
|
|
<li><code>text</code> - static text</li>
|
|
<li><code>header</code> / <code>heading</code> - headers</li>
|
|
<li><code>searchbox</code> - search inputs</li>
|
|
<li><code>switch</code> - toggle switches</li>
|
|
<li><code>checkbox</code> - checkboxes</li>
|
|
<li><code>radio</code> - radio buttons</li>
|
|
<li>And more...</li>
|
|
</ul>
|
|
<p>Note: React Native supports both ARIA-compatible (<code>role</code>) and legacy (<code>accessibilityRole</code>) props. Prefer <code>role</code> for consistency with web standards.</p>
|
|
<h2 class="rp-toc-include" id="using-the-wrong-assertion"><a href="#using-the-wrong-assertion" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Using the wrong assertion</h2>
|
|
<span style="color:#a94442;font-weight:bold">Importance: high</span>
|
|
<p>React Native Testing Library provides built-in Jest matchers. Make sure you're using the right ones:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { Pressable</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Text } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> screen } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'button is disabled'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Pressable</span><span style="color:var(--shiki-token-function)"> role</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"button"</span><span style="color:var(--shiki-token-function)"> aria-disabled</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Submit</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">Pressable</span><span style="color:var(--shiki-foreground)">></span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> button</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.getByRole</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'button'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> { name</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> 'Submit'</span><span style="color:var(--shiki-foreground)"> });</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Good - uses RNTL matcher</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(button)</span><span style="color:var(--shiki-token-function)">.toBeDisabled</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ❌ Bad - doesn't use RNTL matcher</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">button</span><span style="color:var(--shiki-foreground)">.props[</span><span style="color:var(--shiki-token-string-expression)">'aria-disabled'</span><span style="color:var(--shiki-foreground)">])</span><span style="color:var(--shiki-token-function)">.toBe</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">true</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p>Common matchers include:</p>
|
|
<ul>
|
|
<li><code>toBeOnTheScreen()</code> - checks if element is rendered (replaces <code>toBeInTheDocument()</code>)</li>
|
|
<li><code>toBeDisabled()</code> - checks if element is disabled</li>
|
|
<li><code>toHaveTextContent()</code> - checks text content</li>
|
|
<li><code>toHaveAccessibleName()</code> - checks accessible name</li>
|
|
<li>And more...</li>
|
|
</ul>
|
|
<h2 class="rp-toc-include" id="using-query-variants-for-anything-except-checking-for-non-existence"><a href="#using-query-variants-for-anything-except-checking-for-non-existence" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Using <code>query*</code> variants for anything except checking for non-existence</h2>
|
|
<span style="color:#a94442;font-weight:bold">Importance: high</span>
|
|
<p>Use <code>queryBy*</code> only when checking that an element doesn't exist:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { View</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Text } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> screen } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'checks non-existence'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Hello</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Good - uses queryBy for non-existence check</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">screen</span><span style="color:var(--shiki-token-function)">.queryByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Goodbye'</span><span style="color:var(--shiki-foreground)">)).</span><span style="color:var(--shiki-token-constant)">not</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ❌ Bad - uses queryBy when element should exist</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // const element = screen.queryByText('Hello');</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // expect(element).toBeOnTheScreen();</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Good - uses getBy when element should exist</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">screen</span><span style="color:var(--shiki-token-function)">.getByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Hello'</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<h2 class="rp-toc-include" id="using-waitfor-to-wait-for-elements-that-can-be-queried-with-find"><a href="#using-waitfor-to-wait-for-elements-that-can-be-queried-with-find" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Using <code>waitFor</code> to wait for elements that can be queried with <code>find*</code></h2>
|
|
<span style="color:#a94442;font-weight:bold">Importance: high</span>
|
|
<p>Use <code>findBy*</code> queries instead of <code>waitFor</code> + <code>getBy*</code>:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { View</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Text } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> screen</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> waitFor } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'waits for element'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-function)"> Component</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-constant)">show</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> setShow</span><span style="color:var(--shiki-foreground)">] </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-constant)"> React</span><span style="color:var(--shiki-token-function)">.useState</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">false</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-constant)"> React</span><span style="color:var(--shiki-token-function)">.useEffect</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> setTimeout</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-function)"> setShow</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">true</span><span style="color:var(--shiki-foreground)">)</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> 100</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> []);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">>{show </span><span style="color:var(--shiki-token-keyword)">&&</span><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Loaded</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>}</</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">>;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> };</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(<</span><span style="color:var(--shiki-token-constant)">Component</span><span style="color:var(--shiki-foreground)"> />);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Good - uses findBy query</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> element</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.findByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Loaded'</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(element)</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ❌ Bad - uses waitFor + getBy</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // await waitFor(() => {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // expect(screen.getByText('Loaded')).toBeOnTheScreen();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // });</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<h2 class="rp-toc-include" id="performing-side-effects-in-waitfor"><a href="#performing-side-effects-in-waitfor" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Performing side-effects in <code>waitFor</code></h2>
|
|
<span style="color:#a94442;font-weight:bold">Importance: high</span>
|
|
<p>Don't perform side-effects in <code>waitFor</code> callbacks:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { Pressable</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Text</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> View } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> screen</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> waitFor</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> fireEvent } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'avoids side effects in waitFor'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-function)"> Component</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-constant)">count</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> setCount</span><span style="color:var(--shiki-foreground)">] </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-constant)"> React</span><span style="color:var(--shiki-token-function)">.useState</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">0</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-foreground)"> (</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Pressable</span><span style="color:var(--shiki-token-function)"> role</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"button"</span><span style="color:var(--shiki-token-function)"> onPress</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-function)"> setCount</span><span style="color:var(--shiki-foreground)">(count </span><span style="color:var(--shiki-token-keyword)">+</span><span style="color:var(--shiki-token-constant)"> 1</span><span style="color:var(--shiki-foreground)">)}></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Increment</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">Pressable</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Count: {count}</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> };</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(<</span><span style="color:var(--shiki-token-constant)">Component</span><span style="color:var(--shiki-foreground)"> />);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> button</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.getByRole</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'button'</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ❌ Bad - side effect in waitFor</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // await waitFor(async () => {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // await fireEvent.press(button);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // expect(screen.getByText('Count: 1')).toBeOnTheScreen();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // });</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Good - side effect outside waitFor</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-constant)"> fireEvent</span><span style="color:var(--shiki-token-function)">.press</span><span style="color:var(--shiki-foreground)">(button);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> waitFor</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">screen</span><span style="color:var(--shiki-token-function)">.getByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Count: 1'</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> });</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<h2 class="rp-toc-include" id="using-container-to-query-for-elements"><a href="#using-container-to-query-for-elements" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Using <code>container</code> to query for elements</h2>
|
|
<span style="color:#a94442;font-weight:bold">Importance: high</span>
|
|
<p>React Native Testing Library provides a <code>container</code> object that has a <code>queryAll</code> method, but you should avoid using it directly:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { View</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Text } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'finds element incorrectly'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-foreground)"> { </span><span style="color:var(--shiki-token-constant)">container</span><span style="color:var(--shiki-foreground)"> } </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-token-function)"> testID</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"message"</span><span style="color:var(--shiki-foreground)">>Hello</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ❌ Bad - using container.queryAll directly</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> element</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> container</span><span style="color:var(--shiki-token-function)">.queryAll</span><span style="color:var(--shiki-foreground)">((node) </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-constant)"> node</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">props</span><span style="color:var(--shiki-foreground)">.testID </span><span style="color:var(--shiki-token-keyword)">===</span><span style="color:var(--shiki-token-string-expression)"> 'message'</span><span style="color:var(--shiki-foreground)">)[</span><span style="color:var(--shiki-token-constant)">0</span><span style="color:var(--shiki-foreground)">];</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Good - use proper queries</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // const element = screen.getByTestId('message');</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p>Instead, use the proper query methods from <code>screen</code> or the <code>render</code> result. The <code>container</code> is a low-level API that you rarely need.</p>
|
|
<h2 class="rp-toc-include" id="passing-an-empty-callback-to-waitfor"><a href="#passing-an-empty-callback-to-waitfor" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Passing an empty callback to <code>waitFor</code></h2>
|
|
<span style="color:#a94442;font-weight:bold">Importance: high</span>
|
|
<p>Don't pass an empty callback to <code>waitFor</code>:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { View } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> waitFor } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'waits correctly'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(<</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-token-function)"> testID</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"test"</span><span style="color:var(--shiki-foreground)"> />);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ❌ Bad - empty callback</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // await waitFor(() => {});</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Good - meaningful assertion</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> waitFor</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">screen</span><span style="color:var(--shiki-token-function)">.getByTestId</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'test'</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> });</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<h2 class="rp-toc-include" id="not-using-screen"><a href="#not-using-screen" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Not using <code>screen</code></h2>
|
|
<span style="color:#8a6d3b;font-weight:bold">Importance: medium</span>
|
|
<p>You can get all the queries from the <code>render</code> result:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { View</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Text } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'renders component'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-foreground)"> { </span><span style="color:var(--shiki-token-constant)">getByText</span><span style="color:var(--shiki-foreground)"> } </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Hello</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-function)">getByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Hello'</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p>But you can also get them from the <code>screen</code> object:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { View</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Text } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> screen } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'renders component'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Hello</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">screen</span><span style="color:var(--shiki-token-function)">.getByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Hello'</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p>Using <code>screen</code> has several benefits:</p>
|
|
<ol>
|
|
<li>You don't need to destructure <code>getByText</code> from <code>render</code></li>
|
|
<li>It's more consistent with the Testing Library ecosystem</li>
|
|
</ol>
|
|
<h2 class="rp-toc-include" id="wrapping-things-in-act-unnecessarily"><a href="#wrapping-things-in-act-unnecessarily" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Wrapping things in <code>act</code> unnecessarily</h2>
|
|
<span style="color:#8a6d3b;font-weight:bold">Importance: medium</span>
|
|
<p>React Native Testing Library's <code>render</code>, <code>renderHook</code>, <code>userEvent</code>, and <code>fireEvent</code> are already wrapped in <code>act</code>, so you don't need to wrap them yourself:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { Pressable</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Text</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> View } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> fireEvent</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> screen } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'updates on press'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-function)"> Component</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-constant)">count</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> setCount</span><span style="color:var(--shiki-foreground)">] </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-constant)"> React</span><span style="color:var(--shiki-token-function)">.useState</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">0</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-foreground)"> (</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Pressable</span><span style="color:var(--shiki-token-function)"> role</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"button"</span><span style="color:var(--shiki-token-function)"> onPress</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-function)"> setCount</span><span style="color:var(--shiki-foreground)">(count </span><span style="color:var(--shiki-token-keyword)">+</span><span style="color:var(--shiki-token-constant)"> 1</span><span style="color:var(--shiki-foreground)">)}></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Count: {count}</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">Pressable</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> };</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(<</span><span style="color:var(--shiki-token-constant)">Component</span><span style="color:var(--shiki-foreground)"> />);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> button</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.getByRole</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'button'</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Good - fireEvent is already wrapped in act</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-constant)"> fireEvent</span><span style="color:var(--shiki-token-function)">.press</span><span style="color:var(--shiki-foreground)">(button);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">screen</span><span style="color:var(--shiki-token-function)">.getByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Count: 1'</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ❌ Bad - unnecessary act wrapper</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // await act(async () => {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // await fireEvent.press(button);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // });</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<h2 class="rp-toc-include" id="not-using-user-event-api"><a href="#not-using-user-event-api" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Not using User Event API</h2>
|
|
<span style="color:#8a6d3b;font-weight:bold">Importance: medium</span>
|
|
<p><code>userEvent</code> provides a more realistic way to simulate user interactions:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { Pressable</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Text</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> TextInput</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> View } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> screen</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> userEvent } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'uses userEvent'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> user</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> userEvent</span><span style="color:var(--shiki-token-function)">.setup</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-function)"> Component</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-constant)">value</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> setValue</span><span style="color:var(--shiki-foreground)">] </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-constant)"> React</span><span style="color:var(--shiki-token-function)">.useState</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">''</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-foreground)"> (</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">TextInput</span><span style="color:var(--shiki-token-function)"> aria-label</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"Name"</span><span style="color:var(--shiki-token-function)"> value</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{value} </span><span style="color:var(--shiki-token-function)">onChangeText</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{setValue} /></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Pressable</span><span style="color:var(--shiki-token-function)"> role</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"button"</span><span style="color:var(--shiki-token-function)"> onPress</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-function)"> setValue</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">''</span><span style="color:var(--shiki-foreground)">)}></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Clear</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">Pressable</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> };</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(<</span><span style="color:var(--shiki-token-constant)">Component</span><span style="color:var(--shiki-foreground)"> />);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> input</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.getByLabelText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Name'</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> button</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.getByRole</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'button'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> { name</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> 'Clear'</span><span style="color:var(--shiki-foreground)"> });</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Good - uses userEvent for realistic interactions</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-constant)"> user</span><span style="color:var(--shiki-token-function)">.type</span><span style="color:var(--shiki-foreground)">(input</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-string-expression)"> 'John'</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(input)</span><span style="color:var(--shiki-token-function)">.toHaveValue</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'John'</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-constant)"> user</span><span style="color:var(--shiki-token-function)">.press</span><span style="color:var(--shiki-foreground)">(button);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(input)</span><span style="color:var(--shiki-token-function)">.toHaveValue</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">''</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p><code>userEvent</code> methods are async and must be awaited. Available methods include:</p>
|
|
<ul>
|
|
<li><code>press()</code> - simulates a press</li>
|
|
<li><code>longPress()</code> - simulates long press</li>
|
|
<li><code>type()</code> - simulates typing</li>
|
|
<li><code>clear()</code> - clears text input</li>
|
|
<li><code>paste()</code> - simulates pasting</li>
|
|
<li><code>scrollTo()</code> - simulates scrolling</li>
|
|
</ul>
|
|
<h2 class="rp-toc-include" id="not-querying-by-text"><a href="#not-querying-by-text" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Not querying by text</h2>
|
|
<span style="color:#8a6d3b;font-weight:bold">Importance: medium</span>
|
|
<p>In React Native, text is rendered in <code><Text></code> components. You should query by the text content that users see:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { Text</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> View } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> screen } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'finds text correctly'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Hello World</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Good - queries by visible text</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">screen</span><span style="color:var(--shiki-token-function)">.getByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Hello World'</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ❌ Bad - queries by testID when text is available</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // expect(screen.getByTestId('greeting')).toBeOnTheScreen();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<h2 class="rp-toc-include" id="not-using-testing-library-eslint-plugins"><a href="#not-using-testing-library-eslint-plugins" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Not using Testing Library ESLint plugins</h2>
|
|
<span style="color:#8a6d3b;font-weight:bold">Importance: medium</span>
|
|
<p>There's an ESLint plugin for Testing Library: <a href="https://github.com/testing-library/eslint-plugin-testing-library" target="_blank" rel="noopener noreferrer" class="rp-link"><code>eslint-plugin-testing-library</code></a>. This plugin can help you avoid common mistakes and will automatically fix your code in many cases.</p>
|
|
<p>You can install it with:</p>
|
|
<div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="bash"><code><span class="line"><span style="color:var(--shiki-token-function)">yarn</span><span style="color:var(--shiki-token-string)"> add</span><span style="color:var(--shiki-token-string)"> --dev</span><span style="color:var(--shiki-token-string)"> eslint-plugin-testing-library</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p>And configure it in your <code>eslint.config.js</code> (flat config):</p>
|
|
<div class="rp-codeblock language-js"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="js"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> testingLibrary </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'eslint-plugin-testing-library'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-constant)">testingLibrary</span><span style="color:var(--shiki-foreground)">.configs[</span><span style="color:var(--shiki-token-string-expression)">'flat/react'</span><span style="color:var(--shiki-foreground)">]];</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p>Note: Unlike React Testing Library, React Native Testing Library has built-in Jest matchers, so you don't need <code>eslint-plugin-jest-dom</code>.</p>
|
|
<h2 class="rp-toc-include" id="using-cleanup"><a href="#using-cleanup" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Using <code>cleanup</code></h2>
|
|
<span style="color:#8a6d3b;font-weight:bold">Importance: medium</span>
|
|
<p>React Native Testing Library automatically cleans up after each test. You don't need to call <code>cleanup()</code> manually unless you're using the <code>pure</code> export (which doesn't include automatic cleanup).</p>
|
|
<p>If you want to disable automatic cleanup for a specific test, you can use:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native/pure'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'does not cleanup'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // This test won't cleanup automatically</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(<</span><span style="color:var(--shiki-token-constant)">MyComponent</span><span style="color:var(--shiki-foreground)"> />);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ... your test</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p>But in most cases, you don't need to worry about cleanup at all - it's handled automatically.</p>
|
|
<h2 class="rp-toc-include" id="using-get-variants-as-assertions"><a href="#using-get-variants-as-assertions" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Using <code>get*</code> variants as assertions</h2>
|
|
<span style="color:#3c763d;font-weight:bold">Importance: low</span>
|
|
<p><code>getBy*</code> queries throw errors when elements aren't found, so they work as assertions. However, for better error messages, you might want to combine them with explicit matchers:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { View</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Text } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> screen } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'uses getBy as assertion'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Hello</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Good - getBy throws if not found, so it's an assertion</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> element</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.getByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Hello'</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(element)</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Also good - more explicit</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">screen</span><span style="color:var(--shiki-token-function)">.getByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Hello'</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ❌ Bad - redundant assertion</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // const element = screen.getByText('Hello');</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // expect(element).not.toBeNull(); // getBy already throws if null</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<h2 class="rp-toc-include" id="having-multiple-assertions-in-a-single-waitfor-callback"><a href="#having-multiple-assertions-in-a-single-waitfor-callback" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Having multiple assertions in a single <code>waitFor</code> callback</h2>
|
|
<span style="color:#3c763d;font-weight:bold">Importance: low</span>
|
|
<p>Keep <code>waitFor</code> callbacks focused on a single assertion:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { View</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Text } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> screen</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> waitFor } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'waits with single assertion'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-function)"> Component</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-constant)">count</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> setCount</span><span style="color:var(--shiki-foreground)">] </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-constant)"> React</span><span style="color:var(--shiki-token-function)">.useState</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">0</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-constant)"> React</span><span style="color:var(--shiki-token-function)">.useEffect</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> setTimeout</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-function)"> setCount</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">1</span><span style="color:var(--shiki-foreground)">)</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> 100</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> []);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-foreground)"> (</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Count: {count}</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> };</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(<</span><span style="color:var(--shiki-token-constant)">Component</span><span style="color:var(--shiki-foreground)"> />);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ Good - single assertion per waitFor</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> waitFor</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">screen</span><span style="color:var(--shiki-token-function)">.getByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Count: 1'</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> });</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // If you need multiple assertions, do them after waitFor</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">screen</span><span style="color:var(--shiki-token-function)">.getByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Count: 1'</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toHaveTextContent</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Count: 1'</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ❌ Bad - multiple assertions in waitFor</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // await waitFor(() => {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // expect(screen.getByText('Count: 1')).toBeOnTheScreen();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // expect(screen.getByText('Count: 1')).toHaveTextContent('Count: 1');</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // });</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<h2 class="rp-toc-include" id="using-wrapper-as-the-variable-name"><a href="#using-wrapper-as-the-variable-name" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Using <code>wrapper</code> as the variable name</h2>
|
|
<span style="color:#3c763d;font-weight:bold">Importance: low</span>
|
|
<p>This is not really a "mistake" per se, but it's a common pattern that can be improved. When you use the <code>wrapper</code> option in <code>render</code>, you might be tempted to name your wrapper component <code>Wrapper</code>:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { View } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> screen } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">test</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'renders with wrapper'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-function)"> Wrapper</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-foreground)"> ({ children }</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { children</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-function)"> React</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-function)">ReactNode</span><span style="color:var(--shiki-foreground)"> }) </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> (</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-token-function)"> testID</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"wrapper"</span><span style="color:var(--shiki-foreground)">>{children}</</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(<</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-token-function)"> testID</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"content"</span><span style="color:var(--shiki-foreground)">>Content</</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> wrapper</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> Wrapper</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> });</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">screen</span><span style="color:var(--shiki-token-function)">.getByTestId</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'content'</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p>This works fine, but it's more conventional to name it something more descriptive like <code>ThemeProvider</code> or <code>AllTheProviders</code> (if you're wrapping with multiple providers). This makes it clearer what the wrapper is doing.</p>
|
|
<h2 class="rp-toc-include" id="summary"><a href="#summary" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Summary</h2>
|
|
<p>The key principles to remember:</p>
|
|
<ol>
|
|
<li><strong>Use the right query</strong> - Prefer <code>getByRole</code> as your first choice, use <code>findBy*</code> for async elements, and <code>queryBy*</code> only for checking non-existence</li>
|
|
<li><strong>Use proper assertions</strong> - Use RNTL's built-in matchers (<code>toBeOnTheScreen()</code>, <code>toBeDisabled()</code>, etc.) instead of asserting on props directly</li>
|
|
<li><strong>Handle async operations correctly</strong> - Always <code>await</code> <code>render()</code>, <code>renderHook</code>, <code>fireEvent</code>,and <code>userEvent</code> methods</li>
|
|
<li><strong>Use <code>waitFor</code> correctly</strong> - Avoid side-effects in callbacks, use <code>findBy*</code> instead when possible, and keep callbacks focused</li>
|
|
<li><strong>Follow accessibility best practices</strong> - Prefer ARIA attributes (<code>role</code>, <code>aria-label</code>) over <code>accessibility*</code> props</li>
|
|
<li><strong>Organize code well</strong> - Use <code>screen</code> over destructuring, prefer <code>userEvent</code> over <code>fireEvent</code>, and don't use <code>cleanup()</code></li>
|
|
</ol>
|
|
<p>By following these principles, your tests will be more maintainable, accessible, and reliable.</p><!--/$--></div><div class="container-uhcWmO"><img class="logo-IwzwG8" src="/react-native-testing-library/static/image/abstract-atom.4eca0300ff.avif" alt="Abstract Logo" aria-hidden="true"/><div class="content-uJxcIj"><div class="headlineContainer-NHNT4y"><h1 class="headline-iCUUUl">Need React or React Native
|
|
expertise you can count on?</h1></div><div class="buttonContainer-wOj8Y6"><div class="dark"><a href="https://www.callstack.com/contact" class="button-DogSnd brand-rT2ahT ">Let's talk<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16" class="button-icon-Okk0hT" aria-hidden="true" focusable="false"><path fill="currentColor" d="M9.333 13.333h1.334V12H9.333zm-6.666-2.666h8V12H12v-1.333h1.333V9.333H12V8h-1.333v1.333H4V2.667H2.667zM9.333 8h1.334V6.667H9.333z"></path></svg></a></div></div></div></div><footer class="rp-doc-footer"><div class="rp-doc-footer__edit"></div><div class="rp-doc-footer__divider"></div><div class="container-aZLxg0"><a href="/react-native-testing-library/docs/guides/how-to-query" class="pagerLink-_WIlZJ rp-link"><span class="iconBox-AUO0Le"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 24 24" class="icon-WRLCnG"><path d="M4 20h2V4H4zm8-5v2h2v-2zm-2-4H8v2h2v2h2v-2h8v-2h-8V9h-2zm2-2h2V7h-2z"></path></svg></span><span class="textWrap-lmdyLc"><span class="desc-sp3vRh">Previous page</span><span class="title-hrit_i">How to Query</span></span></a><a href="/react-native-testing-library/docs/guides/llm-guidelines" class="pagerLink-_WIlZJ next-axkYXz rp-link"><span class="textWrap-lmdyLc"><span class="desc-sp3vRh">Next page</span><span class="title-hrit_i">LLM Guidelines</span></span><span class="iconBox-AUO0Le"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 24 24" class="icon-WRLCnG"><path d="M20 20h-2V4h2zm-8-5v2h-2v-2zm2-4h2v2h-2v2h-2v-2H4v-2h8V9h2zm-2-2h-2V7h2z"></path></svg></span></a></div></footer></main></div><aside class="rp-doc-layout__outline rp-scrollbar"><div class="rp-outline"><div class="rp-outline__title">Contents<svg width="14" height="14" class="rp-progress-circle"><circle cx="7" cy="7" r="6" stroke-linecap="round" fill="none" stroke="var(--rp-c-divider-light)" stroke-width="2"></circle><circle cx="7" cy="7" r="6" stroke-linecap="round" fill="none" stroke="var(--rp-c-brand)" stroke-width="2" stroke-dasharray="37.69911184307752" stroke-dashoffset="37.69911184307752" transform="rotate(-90 7 7)" style="transition:stroke-dashoffset 0.3s"></circle></svg></div><nav class="rp-outline__toc rp-scrollbar"><a href="#using-the-wrong-query" class="rp-toc-item rp-link" title="Using the wrong query" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Using the wrong query</span></a><a href="#not-using-byrole-most-of-the-time" class="rp-toc-item rp-link" title="Not using *ByRole query most of the time" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Not using <code>*ByRole</code> query most of the time</span></a><a href="#using-the-wrong-assertion" class="rp-toc-item rp-link" title="Using the wrong assertion" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Using the wrong assertion</span></a><a href="#using-query-variants-for-anything-except-checking-for-non-existence" class="rp-toc-item rp-link" title="Using query* variants for anything except checking for non-existence" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Using <code>query*</code> variants for anything except checking for non-existence</span></a><a href="#using-waitfor-to-wait-for-elements-that-can-be-queried-with-find" class="rp-toc-item rp-link" title="Using waitFor to wait for elements that can be queried with find*" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Using <code>waitFor</code> to wait for elements that can be queried with <code>find*</code></span></a><a href="#performing-side-effects-in-waitfor" class="rp-toc-item rp-link" title="Performing side-effects in waitFor" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Performing side-effects in <code>waitFor</code></span></a><a href="#using-container-to-query-for-elements" class="rp-toc-item rp-link" title="Using container to query for elements" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Using <code>container</code> to query for elements</span></a><a href="#passing-an-empty-callback-to-waitfor" class="rp-toc-item rp-link" title="Passing an empty callback to waitFor" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Passing an empty callback to <code>waitFor</code></span></a><a href="#not-using-screen" class="rp-toc-item rp-link" title="Not using screen" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Not using <code>screen</code></span></a><a href="#wrapping-things-in-act-unnecessarily" class="rp-toc-item rp-link" title="Wrapping things in act unnecessarily" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Wrapping things in <code>act</code> unnecessarily</span></a><a href="#not-using-user-event-api" class="rp-toc-item rp-link" title="Not using User Event API" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Not using User Event API</span></a><a href="#not-querying-by-text" class="rp-toc-item rp-link" title="Not querying by text" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Not querying by text</span></a><a href="#not-using-testing-library-eslint-plugins" class="rp-toc-item rp-link" title="Not using Testing Library ESLint plugins" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Not using Testing Library ESLint plugins</span></a><a href="#using-cleanup" class="rp-toc-item rp-link" title="Using cleanup" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Using <code>cleanup</code></span></a><a href="#using-get-variants-as-assertions" class="rp-toc-item rp-link" title="Using get* variants as assertions" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Using <code>get*</code> variants as assertions</span></a><a href="#having-multiple-assertions-in-a-single-waitfor-callback" class="rp-toc-item rp-link" title="Having multiple assertions in a single waitFor callback" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Having multiple assertions in a single <code>waitFor</code> callback</span></a><a href="#using-wrapper-as-the-variable-name" class="rp-toc-item rp-link" title="Using wrapper as the variable name" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Using <code>wrapper</code> as the variable name</span></a><a href="#summary" class="rp-toc-item rp-link" title="Summary" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Summary</span></a></nav><div class="rp-outline__divider"></div><div class="rp-outline__bottom"></div></div><div class="rp-outline__divider"></div><div class="container-LzbylO"><div><div class="headline-y75_LS">Need help with React or React Native projects?</div><div class="description-muYVs3">We support teams building scalable apps with React and React Native.</div></div><a href="https://www.callstack.com/contact" class="button-DogSnd brand-rT2ahT ">Let's talk<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16" class="button-icon-Okk0hT" aria-hidden="true" focusable="false"><path fill="currentColor" d="M9.333 13.333h1.334V12H9.333zm-6.666-2.666h8V12H12v-1.333h1.333V9.333H12V8h-1.333v1.333H4V2.667H2.667zM9.333 8h1.334V6.667H9.333z"></path></svg></a></div></aside></div></div>
|
|
<div id="__rspress_modal_container"></div>
|
|
</body>
|
|
</html>
|