mirror of
https://github.com/callstack/react-native-testing-library.git
synced 2026-09-18 23:09:04 +08:00
168 lines
76 KiB
HTML
168 lines
76 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head><meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>LLM Guidelines for 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="LLM Guidelines for React Native Testing Library - React Native Testing Library">
|
|
<meta property="og:description" content="Actionable guidelines for writing tests with React Native Testing Library (RNTL) v14.">
|
|
<link rel="icon" href="/react-native-testing-library/logo-light.png">
|
|
<meta name="description" content="Actionable guidelines for writing tests with React Native Testing Library (RNTL) v14."></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/llm-guidelines" 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/llm-guidelines" 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/llm-guidelines" 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/llm-guidelines" 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/llm-guidelines" 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/llm-guidelines" 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--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--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>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="llm-guidelines-for-react-native-testing-library"><a href="#llm-guidelines-for-react-native-testing-library" class="rp-header-anchor rp-link" aria-hidden="true">#</a>LLM Guidelines for 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>
|
|
<p>Actionable guidelines for writing tests with React Native Testing Library (RNTL) v14.</p>
|
|
<h2 class="rp-toc-include" id="core-apis"><a href="#core-apis" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Core APIs</h2>
|
|
<h3 class="rp-toc-include" id="render"><a href="#render" class="rp-header-anchor rp-link" aria-hidden="true">#</a>render</h3>
|
|
<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)">const</span><span style="color:var(--shiki-token-constant)"> result</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 style="color:var(--shiki-token-constant)">Component</span><span style="color:var(--shiki-foreground)"> /></span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> options</span><span style="color:var(--shiki-token-keyword)">?</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>
|
|
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>Option</th><th>Description</th></tr></thead><tbody><tr><td><code>wrapper</code></td><td>React component to wrap the rendered component (e.g., providers)</td></tr></tbody></table></div>
|
|
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>Return</th><th>Description</th></tr></thead><tbody><tr><td><code>rerender(component)</code></td><td>Re-render with a new component (async)</td></tr><tr><td><code>unmount()</code></td><td>Unmount the rendered component (async)</td></tr><tr><td><code>toJSON()</code></td><td>Get JSON representation for snapshots</td></tr><tr><td><code>debug(options?)</code></td><td>Print the component tree to console</td></tr><tr><td><code>container</code></td><td>Root host element of the rendered tree</td></tr><tr><td><code>root</code></td><td>First child host element (your component's root)</td></tr></tbody></table></div>
|
|
<h3 class="rp-toc-include" id="screen"><a href="#screen" class="rp-header-anchor rp-link" aria-hidden="true">#</a>screen</h3>
|
|
<p><strong>Prefer <code>screen</code></strong> over destructuring from <code>render()</code>. Provides all query methods after <code>render()</code> is called.</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)">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 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 style="color:var(--shiki-token-comment)">// Access queries via screen</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>
|
|
<h3 class="rp-toc-include" id="renderhook"><a href="#renderhook" class="rp-header-anchor rp-link" aria-hidden="true">#</a>renderHook</h3>
|
|
<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)">const</span><span style="color:var(--shiki-foreground)"> { </span><span style="color:var(--shiki-token-constant)">result</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> rerender</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> unmount</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)"> renderHook</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-function)"> useMyHook</span><span style="color:var(--shiki-foreground)">()</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> options</span><span style="color:var(--shiki-token-keyword)">?</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>
|
|
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>Option</th><th>Description</th></tr></thead><tbody><tr><td><code>initialProps</code></td><td>Initial props passed to the hook</td></tr><tr><td><code>wrapper</code></td><td>React component to wrap the hook (e.g., providers)</td></tr></tbody></table></div>
|
|
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>Return</th><th>Description</th></tr></thead><tbody><tr><td><code>result.current</code></td><td>Current return value of the hook</td></tr><tr><td><code>rerender(props?)</code></td><td>Re-render hook with new props (async)</td></tr><tr><td><code>unmount()</code></td><td>Unmount the hook (async)</td></tr></tbody></table></div>
|
|
<h2 class="rp-toc-include" id="query-selection"><a href="#query-selection" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Query Selection</h2>
|
|
<ul>
|
|
<li><strong>Prefer <code>getByRole</code></strong> as first choice for querying elements</li>
|
|
<li><strong>Query priority</strong>: <code>getByRole</code> → <code>getByLabelText</code> → <code>getByPlaceholderText</code> → <code>getByText</code> → <code>getByDisplayValue</code> → <code>getByTestId</code> (last resort)</li>
|
|
<li><strong>Use <code>findBy*</code></strong> for elements that appear asynchronously (after API calls, timeouts, state updates)</li>
|
|
<li><strong>Use <code>queryBy*</code> ONLY</strong> for checking non-existence (with <code>.not.toBeOnTheScreen()</code>)</li>
|
|
<li><strong>Never use <code>getBy*</code></strong> for non-existence checks</li>
|
|
<li><strong>Avoid <code>container.queryAll()</code></strong> - use <code>screen</code> queries instead</li>
|
|
<li><strong>Query by visible text</strong>, not <code>testID</code> when text is available</li>
|
|
</ul>
|
|
<h2 class="rp-toc-include" id="assertions"><a href="#assertions" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Assertions</h2>
|
|
<ul>
|
|
<li><strong>Use RNTL matchers</strong> - prefer semantic matchers over prop assertions</li>
|
|
<li><strong>Combine queries with matchers</strong>: <code>expect(screen.getByText('Hello')).toBeOnTheScreen()</code></li>
|
|
<li><strong>No redundant null checks</strong> - <code>getBy*</code> already throws if not found</li>
|
|
</ul>
|
|
<h2 class="rp-toc-include" id="jest-matchers-reference"><a href="#jest-matchers-reference" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Jest Matchers Reference</h2>
|
|
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>Matcher</th><th>Description</th></tr></thead><tbody><tr><td><code>toBeOnTheScreen()</code></td><td>Element is present in the element tree</td></tr><tr><td><code>toBeVisible()</code></td><td>Element is visible (checks style, <code>aria-hidden</code>, <code>accessibilityElementsHidden</code>, ancestors)</td></tr><tr><td><code>toBeEmptyElement()</code></td><td>Element has no children or text content</td></tr><tr><td><code>toContainElement(element)</code></td><td>Element contains another element</td></tr><tr><td><code>toBeEnabled()</code></td><td>Element is not disabled (checks <code>aria-disabled</code>, <code>accessibilityState</code>, ancestors)</td></tr><tr><td><code>toBeDisabled()</code></td><td>Element has <code>aria-disabled</code> or <code>accessibilityState={{ disabled: true }}</code> (checks ancestors)</td></tr><tr><td><code>toBeBusy()</code></td><td>Element has <code>aria-busy</code> or <code>accessibilityState={{ busy: true }}</code></td></tr><tr><td><code>toBeChecked()</code></td><td>Element has <code>aria-checked</code> or <code>accessibilityState={{ checked: true }}</code></td></tr><tr><td><code>toBePartiallyChecked()</code></td><td>Element has <code>aria-checked="mixed"</code> or <code>accessibilityState={{ checked: 'mixed' }}</code></td></tr><tr><td><code>toBeSelected()</code></td><td>Element has <code>aria-selected</code> or <code>accessibilityState={{ selected: true }}</code></td></tr><tr><td><code>toBeExpanded()</code></td><td>Element has <code>aria-expanded</code> or <code>accessibilityState={{ expanded: true }}</code></td></tr><tr><td><code>toBeCollapsed()</code></td><td>Element has <code>aria-expanded={false}</code> or <code>accessibilityState={{ expanded: false }}</code></td></tr><tr><td><code>toHaveTextContent(text)</code></td><td>Element has matching text content</td></tr><tr><td><code>toHaveDisplayValue(value)</code></td><td>TextInput has matching display value</td></tr><tr><td><code>toHaveAccessibleName(name?)</code></td><td>Element has matching <code>aria-label</code>, <code>accessibilityLabel</code>, or text content</td></tr><tr><td><code>toHaveAccessibilityValue(value)</code></td><td>Element has matching <code>aria-value*</code> or <code>accessibilityValue</code></td></tr><tr><td><code>toHaveStyle(style)</code></td><td>Element has matching style</td></tr><tr><td><code>toHaveProp(name, value?)</code></td><td>Element has prop (use semantic matchers when possible)</td></tr></tbody></table></div>
|
|
<h2 class="rp-toc-include" id="user-interactions"><a href="#user-interactions" class="rp-header-anchor rp-link" aria-hidden="true">#</a>User Interactions</h2>
|
|
<p><strong>Prefer <code>userEvent</code></strong> over <code>fireEvent</code> for realistic user interaction simulation. <code>userEvent</code> triggers the complete event sequence that real users would produce.</p>
|
|
<h3 class="rp-toc-include" id="userevent-preferred"><a href="#userevent-preferred" class="rp-header-anchor rp-link" aria-hidden="true">#</a>userEvent (Preferred)</h3>
|
|
<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)">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></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>
|
|
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>Method</th><th>Description</th></tr></thead><tbody><tr><td><code>user.press(element)</code></td><td>Press an element (triggers <code>pressIn</code>, <code>pressOut</code>, <code>press</code>)</td></tr><tr><td><code>user.longPress(element, options?)</code></td><td>Long press with optional <code>{ duration }</code></td></tr><tr><td><code>user.type(element, text, options?)</code></td><td>Type into TextInput (triggers <code>focus</code>, <code>keyPress</code>, <code>change</code>, <code>changeText</code> per char)</td></tr><tr><td><code>user.clear(element)</code></td><td>Clear TextInput (select all + backspace)</td></tr><tr><td><code>user.paste(element, text)</code></td><td>Paste text into TextInput</td></tr><tr><td><code>user.scrollTo(element, options)</code></td><td>Scroll a ScrollView with <code>{ y }</code> or <code>{ x }</code> offset</td></tr></tbody></table></div>
|
|
<h3 class="rp-toc-include" id="fireevent-low-level"><a href="#fireevent-low-level" class="rp-header-anchor rp-link" aria-hidden="true">#</a>fireEvent (Low-level)</h3>
|
|
<p>Use only when <code>userEvent</code> doesn't support the event or when you need direct control.</p>
|
|
<div class="rp-table-scroll-container rp-scrollbar"><table><thead><tr><th>Method</th><th>Description</th></tr></thead><tbody><tr><td><code>fireEvent(element, eventName, ...data)</code></td><td>Fire any event by name</td></tr><tr><td><code>fireEvent.press(element)</code></td><td>Fire <code>onPress</code> only (no <code>pressIn</code>/<code>pressOut</code>)</td></tr><tr><td><code>fireEvent.changeText(element, text)</code></td><td>Fire <code>onChangeText</code> directly</td></tr><tr><td><code>fireEvent.scroll(element, eventData)</code></td><td>Fire <code>onScroll</code> with event data</td></tr></tbody></table></div>
|
|
<h2 class="rp-toc-include" id="asyncawait-v14"><a href="#asyncawait-v14" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Async/Await (v14)</h2>
|
|
<ul>
|
|
<li><strong>Always <code>await</code></strong>: <code>render()</code>, <code>fireEvent.*</code>, <code>renderHook()</code>, <code>userEvent.*</code></li>
|
|
<li><strong>Make test functions <code>async</code></strong>: <code>test('name', async () => { ... })</code></li>
|
|
<li><strong>Don't wrap in <code>act()</code></strong> - <code>render</code> and <code>fireEvent</code> handle it internally</li>
|
|
</ul>
|
|
<h2 class="rp-toc-include" id="waitfor-usage"><a href="#waitfor-usage" class="rp-header-anchor rp-link" aria-hidden="true">#</a>waitFor Usage</h2>
|
|
<ul>
|
|
<li><strong>Use <code>findBy*</code></strong> instead of <code>waitFor</code> + <code>getBy*</code> when waiting for elements</li>
|
|
<li><strong>Never perform side-effects</strong> (like <code>fireEvent.press()</code>) inside <code>waitFor</code> callbacks</li>
|
|
<li><strong>One assertion per <code>waitFor</code></strong> callback</li>
|
|
<li><strong>Never pass empty callbacks</strong> - always include a meaningful assertion</li>
|
|
<li><strong>Place side-effects before <code>waitFor</code></strong> - perform actions, then wait for result</li>
|
|
</ul>
|
|
<h2 class="rp-toc-include" id="code-organization"><a href="#code-organization" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Code Organization</h2>
|
|
<ul>
|
|
<li><strong>Use <code>screen</code></strong> instead of destructuring from <code>render()</code>: <code>screen.getByText()</code> not <code>const { getByText } = render()</code></li>
|
|
<li><strong>Prefer <code>userEvent</code></strong> over <code>fireEvent</code> for realistic interactions</li>
|
|
<li><strong>Don't use <code>cleanup()</code></strong> - handled automatically</li>
|
|
<li><strong>Name wrappers descriptively</strong>: <code>ThemeProvider</code> not <code>Wrapper</code></li>
|
|
<li><strong>Install ESLint plugin</strong>: <code>eslint-plugin-testing-library</code></li>
|
|
</ul>
|
|
<h2 class="rp-toc-include" id="quick-checklist"><a href="#quick-checklist" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Quick Checklist</h2>
|
|
<ul>
|
|
<li>✅ Using <code>getByRole</code> as first choice?</li>
|
|
<li>✅ Using <code>await</code> for all async operations?</li>
|
|
<li>✅ Using <code>findBy*</code> for async elements (not <code>waitFor</code> + <code>getBy*</code>)?</li>
|
|
<li>✅ Using <code>queryBy*</code> only for non-existence?</li>
|
|
<li>✅ Using RNTL matchers (<code>toBeOnTheScreen()</code>, <code>toBeDisabled()</code>, etc.)?</li>
|
|
<li>✅ Using <code>screen</code> not destructuring from <code>render()</code>?</li>
|
|
<li>✅ Avoiding side-effects in <code>waitFor</code>?</li>
|
|
<li>✅ Using <code>userEvent</code> when appropriate?</li>
|
|
</ul>
|
|
<h2 class="rp-toc-include" id="example-good-pattern"><a href="#example-good-pattern" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Example: Good Pattern</h2>
|
|
<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-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 style="color:var(--shiki-token-keyword)">import</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 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>
|
|
<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)">'user can submit form'</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)">name</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> setName</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)"> const</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-constant)">submitted</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> setSubmitted</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-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)"> role</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"textbox"</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)">{name} </span><span style="color:var(--shiki-token-function)">onChangeText</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{setName} /></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-label</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"Submit"</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)"> setSubmitted</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 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)"> {submitted </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-token-function)"> role</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-string-expression)">"alert"</span><span style="color:var(--shiki-foreground)">>Form submitted!</</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)"> // ✅ getByRole as first choice</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)">.getByRole</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'textbox'</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)"> '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)"> 'Submit'</span><span style="color:var(--shiki-foreground)"> });</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ 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 Doe'</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-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>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ findBy* for async elements</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> successMessage</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)">.findByRole</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'alert'</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // ✅ RNTL matchers</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(successMessage)</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)">(successMessage)</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)">'Form submitted!'</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="example-anti-patterns"><a href="#example-anti-patterns" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Example: Anti-Patterns</h2>
|
|
<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-comment)">// ❌ Missing await</span></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)">'bad'</span><span style="color:var(--shiki-token-punctuation)">,</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)"> 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 style="color:var(--shiki-token-constant)"> fireEvent</span><span style="color:var(--shiki-token-function)">.press</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)">'Submit'</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)">// ❌ getBy* for non-existence</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)">'Error'</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)">// ❌ waitFor + getBy* instead of findBy*</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)">'Loaded'</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)">// ❌ Side-effect in 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)">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-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-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)">'Result'</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)">// ❌ accessibility* props instead of ARIA</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)"> accessibilityRole</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)"> accessibilityLabel</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)">// ❌ Destructuring from render</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 style="color:var(--shiki-token-constant)">Component</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>By following these guidelines, 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/common-mistakes" 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">Common Mistakes</span></span></a><a href="/react-native-testing-library/docs/guides/troubleshooting" class="pagerLink-_WIlZJ next-axkYXz rp-link"><span class="textWrap-lmdyLc"><span class="desc-sp3vRh">Next page</span><span class="title-hrit_i">Troubleshooting</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="#core-apis" class="rp-toc-item rp-link" title="Core APIs" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Core APIs</span></a><a href="#render" class="rp-toc-item rp-link" title="render" style="padding-left:12px" data-depth="1"><span class="rp-toc-item__text rp-doc">render</span></a><a href="#screen" class="rp-toc-item rp-link" title="screen" style="padding-left:12px" data-depth="1"><span class="rp-toc-item__text rp-doc">screen</span></a><a href="#renderhook" class="rp-toc-item rp-link" title="renderHook" style="padding-left:12px" data-depth="1"><span class="rp-toc-item__text rp-doc">renderHook</span></a><a href="#query-selection" class="rp-toc-item rp-link" title="Query Selection" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Query Selection</span></a><a href="#assertions" class="rp-toc-item rp-link" title="Assertions" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Assertions</span></a><a href="#jest-matchers-reference" class="rp-toc-item rp-link" title="Jest Matchers Reference" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Jest Matchers Reference</span></a><a href="#user-interactions" class="rp-toc-item rp-link" title="User Interactions" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">User Interactions</span></a><a href="#userevent-preferred" class="rp-toc-item rp-link" title="userEvent (Preferred)" style="padding-left:12px" data-depth="1"><span class="rp-toc-item__text rp-doc">userEvent (Preferred)</span></a><a href="#fireevent-low-level" class="rp-toc-item rp-link" title="fireEvent (Low-level)" style="padding-left:12px" data-depth="1"><span class="rp-toc-item__text rp-doc">fireEvent (Low-level)</span></a><a href="#asyncawait-v14" class="rp-toc-item rp-link" title="Async/Await (v14)" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Async/Await (v14)</span></a><a href="#waitfor-usage" class="rp-toc-item rp-link" title="waitFor Usage" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">waitFor Usage</span></a><a href="#code-organization" class="rp-toc-item rp-link" title="Code Organization" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Code Organization</span></a><a href="#quick-checklist" class="rp-toc-item rp-link" title="Quick Checklist" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Quick Checklist</span></a><a href="#example-good-pattern" class="rp-toc-item rp-link" title="Example: Good Pattern" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Example: Good Pattern</span></a><a href="#example-anti-patterns" class="rp-toc-item rp-link" title="Example: Anti-Patterns" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Example: Anti-Patterns</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>
|