리액트 네이티브 테스트 스위트가 녹색이지만 사용자가 실제 장치에서 "Continue"를 탭했을 때 아무런 반응도 하지 않는다고 보고합니다. 컴포넌트 테스트에서는 버튼을 찾았고 핸들러를 호출했으며 기대하는 화면을 모킹된 자바스크립트 환경에서 보았습니다. 그러나 실제 네이티브 권한 요청 프롬프트, 키보드 동작, 애니메이션, 플랫폼 API, 또는 실제 네비게이션 스택을 확인하지 않았습니다.
그것은 팀이 잘못된 자신감을 얻는 곳입니다. 리액트 네이티브 테스트 라이브러리 컴포넌트가 렌더링하는 것을 테스트하고 사용자 상호 작용에 어떻게 반응하는지 테스트하기에는 훌륭하지만 장치 테스트 또는 성능 측정의 대체품은 아닙니다. 신뢰할 수 있는 전략은 각层에서 실패를 노출할 수 있는 부분을 사용하는 것입니다.
목차
- 사용자 중심 테스트가 모든 것을 바꾼다
- 설치 및 구성: 실제로 작동하는 것
- 핵심 API: 쿼리 및 어설션을 설명한다
- 컴포넌트, 훅스 및 네비게이션의 실제 패턴
- CI 및 성능 검사에서 불안정한 테스트 디버깅
- 모든 것을 함께 구축하고 앞으로 나아가세요
사용자 중심 테스트가 모든 것을 바꾸는 이유
A 테스트가 실패하는 이유는 테스트 자체가 작성되기 전에 이미 발생합니다. 개발자는 컴포넌트의 props를 검사하고 컴포넌트의 상태에 접근하거나 큰 스냅샷을 비교하는 이유는 assertion이 쉽기 때문입니다. 테스트가 통과하면 컴포넌트 구조가 변경되어도 사용자 경험은 변경되지 않으면 테스트 스위트가 실패합니다. 심지어 테스트는 계속 통과할 수 있지만 사용자에게 보이는 동작이 잘못된 이유는 assertion이 사용자가 필요한 것을 보는 것을 설명하지 않았기 때문입니다.
React Native Testing Library는 반대 접근법을 취합니다. 컴포넌트를 렌더링하고 사용자가 볼 수 있는 컨트롤을 통해 컴포넌트와 상호 작용한 다음 사용자가 볼 수 있는 결과를 확인합니다. 이 접근법은 React Native Testing Library의 사용자 중심 예시 그리고 React Native의 테스트 지침을 따릅니다. 테스트를 짧게 유지하고 각 테스트가 하나의 일에 집중하고 뷰 관련 문제를 비즈니스 로직과 상태에서 분리하고 내부 implementation details 대신 사용자에게 보이는 출력 또는 접근성 도우미를 선호합니다.

사용자가 의존하는 동작을 테스트하세요.
로그인 폼의 제출 버튼이 요청이 실행되는 동안 비활성화된 경우 brittle 테스트는 disabled 특정 컴포넌트 인스턴스를 검사하거나 상태 변수가 변경되었는지 확인하는 이유는 assertion이 쉽기 때문입니다. 더 강한 테스트는 접근 가능한 '로그인' 버튼을 누르고 로딩 인디케이터를 기다리며 오류 메시지나 목적지 화면이 나타나는지 확인합니다.
2번째 테스트는 폼이 로컬 상태, 리듀서, 커스텀 훅, 또는 다른 버튼 구현을 사용하는지 여부에 관계없이 앱이 올바른 결과를 전달하는지에만 관심이 있습니다.
실용적인 규칙: 사용자가 관찰할 수 없는 경우 컴포넌트 동작 테스트에 속하는지 여부를 의심하는 것이 좋습니다.
접근성 레이블 및 역할에 기반한 쿼리도 더 나은 제품 code를 강제합니다. 의미 있는 레이블을 노출하는 화면은 보조 기술과 테스트를 수행하는 데 더 쉽습니다. 이러한 연결은 더 광범위한 앱 사용자 경험을 평가할 때 중요합니다. 앱 사용자 경험테스트 가능성과 사용성은 종종 함께 개선되기 때문에 이러한 연결은 중요합니다.
성공한 테스트가 증명하는 것은 gì일까요?
사용자 중심 컴포넌트 테스트는 자바스크립트가 예상되는 branch를 렌더링하고 시뮬레이션된 클릭에 응답하는지 증명할 수 있습니다. 그러나 생체 인증 프롬프트가 올바르게 열리는지, 네이티브 카메라가 사용 가능한 결과를 반환하는지, 또는 플랫폼별 라이프사이클 동작에 따라 결제 흐름이 살아남는지는 증명할 수 없습니다.
이 경계는 라이브러리의 약점이 아니라 테스트层의 진실성을 유지하는 이유입니다. RNTL을 컴포넌트 동작에 사용하고, 네이티브 통합, 실제 탐색, 권한, 인증, 결제, 또는 앱의 핵심 기능이 결과를 변경할 수 있는 흐름에만 장치 기반 테스트를 사용하는 것이 좋습니다.
설치 및 실제로 작동하는 구성
최신 설정은 스코프 패키지를 시작합니다:
@testing-library/react-native
더 오래된 react-native-testing-library npm 패키지 이름은 역사적인 유물로 남아 있지만 현재 프로젝트에서는 Testing Library 가족 내에서 관리되는 스코프 패키지를 사용해야 합니다. 프로젝트의 GitHub 저장소 는 React Native를위한 테스트 관행을 장려하는 유틸리티로 설명하고, 릴리스 기록은 React Native와 함께 계속해서 변경되는 대신 정적 헬퍼가 아닌 라이브러리가 계속해서 변경되고 있음을 보여줍니다.
기존 Jest 환경과 함께 라이브러리를 설치하세요. Expo 프로젝트는 일반적으로 Expo Jest preset를 사용하며, bare React Native 프로젝트는 React Native preset를 사용할 수 있습니다:
npm install --save-dev @testing-library/react-native jest
Expo에 대해 프로젝트가 이미 사용하는 preset을 추가하세요:
{
"scripts": {
"test": "jest"
},
"jest": {
"preset": "jest-expo"
}
}
bare React Native 애플리케이션을 사용하는 경우 대응하는 React Native Jest 구성 대신 사용하세요. 프레임워크 버전과 일치시켜야 합니다. RNTL 문제로 보이는 많은 실패는 React 렌더러, Babel 변환, 또는 Jest preset의 불일치로 인한 것입니다.
설정 파일을 명확하게 유지하세요
공유 환경 설정을 설정 파일에 넣어두고, 테스트마다 반복적으로 모킹을 사용하지 마세요:
// jest.setup.js
import '@testing-library/react-native/extend-expect';
그런 다음 Jest에서 참조하세요:
{
"jest": {
"preset": "jest-expo",
"setupFilesAfterEnv": ["<rootDir>/jest.setup.js"]
}
}
앱이 React Navigation, Reanimated, 제스처 처리, safe-area 컨텍스트, 또는 저장소 모듈을 사용하는 경우, 테스트 환경이 필요로 하는 모킹만 구성하세요. 모든 테스트를 통과하기 위해 애플리케이션 동작을 변경하는 글로벌 모킹은 테스트 스위트의 신뢰성을 떨어뜨립니다.
TypeScript도 같은 주의가 필요합니다. Jest 변환과 .ts 그리고 .tsx 파일을 preset 또는 Babel 설정을 통해 전달하고 컴파일러에 테스트 유형을 유지하세요. 로컬에서 실행되는 테스트지만 타입 체크되지 않은 테스트는 잘못된 쿼리 이름, 유효하지 않은 네비게이션 매개 변수 또는 안전하지 않은 모의 모양을 숨길 수 있습니다.
릴리스 시간표는 이전 설정 조언을 진단할 때 유용합니다. 프로젝트 목록 127 릴리스,에 v14.0.1 2026-06-23에 태그되었습니다., v12.9.0, 2024-11-27에 출시되었으며 React Native 0.77 및 Expo 52에 대한 공식 지원을 추가했습니다.. v14 alpha 라인은 2025년 3월 Universal Test Renderer에서 deprecated React Test Renderer로 이동하여 React 19만 지원하기 위해 준비되었습니다. 이러한 세부 정보는 RNTL 릴리스 역사에서 나타납니다.
따라서 outdated 튜토리얼에서 renderer 의존성을 복사하지 말고 앱의 버전을 확인하세요. 실용적인 Jest 기초를 위해, Jest 단위 테스트 가이드와 비교하세요.그 다음에는 작은 컴포넌트 테스트를 실행하기 전에 네비게이션 및 네이티브 모킹을 추가합니다.

코어 API, 쿼리 및 어설션에 대한 설명
RNTL 테스트는 사용자가 볼 수 있는, 찾을 수 있는, 그리고 사용할 수 있는 쿼리와 일치할 때 신뢰할 수 있습니다. API은 작지만, 구현 세부 정보를 노출하는 선택자만을 선택하는 경우 통과 테스트가 오해를 일으킬 수 있습니다.
시작하세요 render:
const screen = render(<LoginForm />);
사용자에게 가장 관련이 있는 쿼리를 선택하세요. 접근성에 관련된 쿼리를 우선으로 사용할 수 있는 경우, 텍스트가 동작할 때는 보이는 텍스트를 사용하고, 의미 있는 사용자 인터페이스 선택자나 안정적인 통합 훅이 필요할 때는 testID 인포그래픽 피라미드 차트로 소프트웨어 테스트 자동화에서 쿼리의 권장 우선순위를 보여줍니다.

각 쿼리 패밀리는 다음과 같은 특수한 목적을 가지고 있습니다:
동시성 존재:
- 사용 사용
getByRole,getByText또는 다른getBy이미 존재해야 하는 요소가 이미 존재하지 않으면 테스트는 즉시 실패합니다. - 동기식 표시: 사용
findByRole또는findByText렌더링 또는 상호 작용이 비동기 업데이트를 유발할 때 - 미출시 확인: 사용
queryByText또는queryByTestId요소가 존재하지 않을 수 있고 null 결과가 예상되는 대신 예외가 발생하는 경우 - 대체 선택자: 사용
getByTestId자발적으로. 복잡한 제어를 위한 견고한 hook을 제공하지만 앱 내에서 접근 가능성 있는 레이블을 대체하지 않도록 한다.
집중된 이벤트 테스트를 위해 fireEvent.press 는 직접적이다:
fireEvent.press(screen.getByRole('button', { name: 'Save' }));
사용 userEvent 설치된 버전이 더 현실적인 상호 작용 순서를 지원할 때 사용하라. 어느 쪽이든 결과적인 UI를 확인하라:
expect(await screen.findByText('Saved')).toBeTruthy();
핸들러 확인은 이벤트 콜백을 포함하는 컴포넌트의 공개 계약을 적합하게 맞추는 것이다. 단지 사용자 경험의 작동 여부를 증명하는 유일한 증거이다.
스냅샷 대신 구체적인 확인을 선호하라
좋은 확인은 화면을 설명한다:
expect(screen.getByText('Account created')).toBeTruthy();
expect(screen.getByRole('button', { name: 'Continue' })).toBeEnabled();
그것들은 또한 접근성 상태, 선택, 그리고 표시된 유효성 피드백을 확인할 수 있다. 내부 연결을 확인하지 말라:
expect(screen.getByTestId('submit-button').props.onPress).toBeDefined();
그 확인은 프로퍼티가 존재한다는 것을 증명한다, 하지만 기능이 작동하는지 증명하지는 않는다. 작은, 의도적인 스냅샷은 구조적인 변경을 잡을 수 있지만, 큰 네비게이션 또는 화면 스냅샷은 노이즈가 많은 리뷰를 만들고, 설명되지 않은 업데이트를 쉽게 승인할 수 있다.
테스트 라이브러리 패키지는 더 광범위한 testing-library npm @testing-library/react-native버전과 함께 2026년 13.3.3 버전이 출시되었습니다.프로젝트의 저장소 정보에 따라. 플랫폼 간 공유된 쿼리 규칙은 제품 동작을 나타내는 어설션을 결정하지 않습니다.
Jest 컴포넌트 테스트 관행에 대한 더 광범위한 비교를 보려면 이 유닛 테스트 가이드를 참조하세요. React. RNTL은 자바스크립트 렌더링된 컴포넌트 경계까지 멈추지만. 네이티브 권한, 실제 네비게이션 스택, 장치 키보드, 프레임 타이밍 및 메모리 동작은 E2E 또는 성능 도구를 사용하여 더 많은 컴포넌트 모킹 대신 필요합니다.
아래의 비디오는 쿼리 및 어설션 워크플로우를 컨텍스트에서 보여줍니다.
컴포넌트, 훅스 및 네비게이션에 대한 실용적인 패턴
유용한 테스트 스위트는 애플리케이션의 형태를 따릅니다. 프레젠테이션 컴포넌트는 직접 동작 테스트가 필요하고, 훅스는 제어된 입력과 출력이 필요하고, 네비게이션은 충분히 현실적인 제공자가 필요하고, 네이티브 모듈은 실제 장치 검증과 구분되는 모킹이 필요합니다.

표현적 컴포넌트
컴포넌트 테스트는 공개 계약과 가깝게 유지하세요:
const onSelect = jest.fn();
render(
<PlanCard
title="Team"
description="Shared workspace"
onSelect={onSelect}
/>
);
fireEvent.press(screen.getByRole('button', { name: 'Choose Team' }));
expect(onSelect).toHaveBeenCalled();
정확한 레이블은 UI와 일치해야 합니다. 중요한 것은 테스트가 사용자나 접근성 서비스가 찾는 방식으로 컨트롤을 찾고, 중요하지 않은 callback 결과를 확인하는 것입니다. 기본적으로 모든 자식 컴포넌트를 모킹하지 마세요. 비용이 많이 드는 또는 관련이 없는 경계만 모킹하세요. 테스트하려는 동작이 가려지지 않도록 하세요.
커스텀 훅을 사용할 때 renderHook 설치된 RNTL 버전이 제공하는 경우:
const { result } = renderHook(() => useSearch());
await act(async () => {
await result.current.submit('query');
});
expect(result.current.status).toBe('success');
훅 테스트는 네트워크 또는 저장소 경계를 제어해야 하며, 전체 앱을 재현하지 마세요. 화면을 별도로 테스트하여 훅의 상태가 유용한 UI가 되는지 확인하세요.
네비게이션 및 비동기 데이터
네비게이션 동작에 대해, 실제 NavigationContainer 작은 테스트 네비게이터를 렌더링하는 것이 모킹된 모든 네비게이션 메소드보다 더 가치가 있습니다. 표시된 컨트롤을 클릭하고, 목적지 콘텐츠를 기다리며, 새로운 화면의 출력을 확인하세요. 직접 useNavigation 작은 버튼의 경우, 단지 타입된 경로를 디스패치하는 책임만 있는 경우 모킹은 여전히 적절합니다. 그러나 경로 등록, 매개변수, 또는 중첩 네비게이션 동작을 검증하지 않습니다.
비동기 데이터도 동일한 discipline을 적용하세요. API 또는 저장소 응답을 모킹하세요. 화면을 렌더링하고, 로딩 상태를 확인하세요. 요청을 해결하고, 성공 또는 오류 출력을 확인하세요. 기대되는 최종 요소에 대한 쿼리 사용하고, 거부된 요청을 명확하게 하세요. 그렇지 않으면 테스트는 컴포넌트가 의도한 branch로 도달하지 못했기 때문에 통과할 수 있습니다. findBy 테스트
자연스러운 모듈 mocks
AsyncStorage, 권한, 카메라, 생체 인식, 플랫폼 API에 대한 mocks는 결정론적인 자바스크립트 테스트에 유용합니다. 그들은 네이티브 기능이 작동하는 증거가 아닙니다. 모듈 계약에 가까운 mock 동작을 유지하고 테스트 사이에 호출을 초기화하고 실패 응답을 포함하여 오직 행복한 경로만 모델링하는 대신.
| 시나리오 | RNTL과 함께 가장 좋습니다 | E2E 검증이 필요합니다 |
|---|---|---|
| 형식 검증 및 표시 오류 | Yes | 네 |
| 로딩, 성공, 오류 UI를 모킹된 저장소에서 | Yes | 생산 환경의 중요한 흐름 |
| 등록된 화면 간의 네비게이션 | Yes, 테스트 네비게이터를 사용합니다. | Yes, 제스처, 심층 링크, 또는 플랫폼 동작이 중요한 경우 |
| AsyncStorage 상태 결정 | Yes, 제어된 모킹을 사용합니다. | Yes, 런칭과 지속성이 네이티브 라이프 사이클과 상호 작용할 때 |
| 카메라, 생체 인식, 권한, 또는 플랫폼 API | JS 대체 및 branch 로직 | Yes, 실제 장치 또는 대표 장치에서 |
| 레이아웃, 렌더링 성능, 및 네이티브 code | No | Yes, 장치 또는 특수 도구를 사용합니다. |
경계는 실제로 실현 가능한 것입니다: 의존성을 테스트하는 JavaScript 결정을 모킹하고, 의존성의 실제 동작을 확인하기 위해 장치를 실행합니다.
CI 및 성능 검사
불안정한 테스트는 시간, 공유 상태, 또는 UI와 경쟁하는 어설션을 나타낼 수 있습니다. 시간 초과를 설정하기 전에 해당 조건을 식별하십시오. 더 긴 시간 초과는 스케줄링 문제를 숨기고 테스트 스위트를 느리게 만들 수 있습니다.
사용 findBy 업데이트 후 나타날 것으로 예상되는 요소에 대해 사용 waitFor 상태 조건 또는 모의 호출에 대해 사용 act 가짜 타이머가 활성화된 경우, 상호 작용이 필요할 때 타이머를 앞서고 실제 타이머를 나중에 복원하십시오. await, 사용자 상호 작용, 또는 타이머 플러시 대신 경고를 억제하는 대신.
CI 실패를 재현하십시오
신뢰할 수 있는 CI 작업은 lockfile에서 설치, 로컬에서 사용하는 동일한 Jest 명령어를 실행, 그리고 모의 상태를 분리합니다. 테스트 간에 모의 호출을 초기화하고 모듈을 초기화할 때 모듈 수준 상태가 동작에 영향을 미치는 경우, 모듈을 초기화하고 실행 순서에 의존하지 않는 종속성을 제거하십시오. Jest 캐싱은 feedback를 빠르게 하지만 종속성 또는 구성 변경은 적절한 캐시 무효화를 필요로 합니다.
CI 전용 실패는 컴포넌트 리팩토링 전에 환경 비교를 필요로 합니다. Node, 패키지 매니저, Jest 워커 설정, 타이머 구성, 및 환경 변수를 확인하십시오. 가능한 경우 로컬에서 동일한 명령어를 재현하고 실패하는 테스트를 줄이십시오.
관찰성은 다른 단계를 채우고 있습니다. React Native에 대한 도구인 Sentry 실제 장치 및 네이티브 통합과 관련된 실패를 포함하여 모킹된 컴포넌트 테스트로 재현할 수 없는 생산 오류의 맥락을 제공합니다.
보안에 민감한 여행에 두 번째 경계가 필요합니다. 컴포넌트 테스트를 사용하여 유효성 검사 및 상태 전환을 수행한 다음 장치 수준의 보장을 추가하여 핸드오프 및 네이티브 동작을 테스트합니다. 일회용 code 흐름에 대한 경우, 일회용 흐름이 여행의 일부가 될 때 SMS 인증 흐름을 테스트하는 방법에 대한 지침을 참조하십시오. 성능을 측정으로 대신 주장하지 마십시오. integration이 여행의 일부가 될 때
성능을 측정으로 대신 성명으로 다루세요.
측정 규칙: 성능 테스트 문서 모든 것을 함께 조합하고 앞으로 나아가십시오.
measurement
regression CI
pull-request
React Native Testing Library는 테스트 전략의 빠른 층에 속합니다. 컴포넌트 동작, 가시적인 상태 변경, 접근성 결과, 유효성 검사, 가짜 데이터 상태 및 자바스크립트 컴포넌트 간의 통합을 포함하는 큰 범위의 테스트를 수행해야 합니다. 사용자가 관찰할 수 있는 테스트에 집중하고, 실패가 큰 렌더링 tree 대신 특정 동작에 대한 지시를 제공하십시오.
리액트 네이티브의 테스트 라이브러리는 작은 장치 기반层에서 흐름을 보호하는 데 도움이 됩니다. 실용적인 마이그레이션 경로 기존의 테스트 스위트를 한 번에 다시 작성할 필요가 없습니다.
가치 있는 비즈니스 테스트를 유지하십시오.
순수한 상태와 도메인 로직을 집중된 단위 테스트로 옮기십시오. 그들이 명확한 feedback를 제공할 때.
- implementation assertions를 먼저 대체하십시오. 속성 및 내부 상태 검사를 가시적인 출력, 접근성 상태 및 상호 작용 결과로 변경하십시오.
- 샷샷을 줄이십시오. 리뷰어들이 이해하고 유지할 수 있는 샷샷만 유지하십시오.
- testing overview practical migration path
- 자연스러운 경계 커버리지 추가. 모든 중요한 모킹된 모듈에 대해, 여전히 유효성 검증이 필요한 장치 동작을 식별하십시오.
- 중요한 여행을 보호하십시오. 인증, 결제, 핵심 네비게이션, 권한, 기타 흐름에서 네이티브 동작이 결과를 변경할 수 있는 경우 E2E 커버리지 추가.
- Sensitive 화면을 별도로 측정하십시오. 리스트, 피드, 비용이 많이 드는 렌더 경로 대신 Jest 지속 시간에서 추측하기보다 반복적인 성능 비교를 사용하십시오.
For release confidence, connect the suite to Capgo. 올바른 질문은 React Native Testing Library가 앱의 전체 테스트를 수행할 수 있는지 여부가 아닙니다. 그것은 할 수 없으며, 공식 경계는 유용합니다. 올바른 질문은 각 중요한 위험에 대해 테스트가 실행되는 환경에서 노출할 수 있는지 여부입니다. Capgo는 유효성 검증된 JavaScript 및 자산 변경을 CapacitorJS 및 Electron 팀에 대한 제어된 배포에 연결합니다. 대상 채널, 롤아웃 시각화, 롤백 보호를 제공합니다. Capgo를 방문하십시오.
__CAPGO_KEEP_0__
Capgo Capgo 이러한 기능을 컴포넌트, E2E, CI 테스트 워크플로우와 함께 사용할 수 있는지 확인하세요.