[React Native] 통합 앱에서 프로파일 회귀 테스트를 설계하는 방법
React Native 통합 앱에서 프로파일 회귀 테스트를 설계하는 방법
단일 앱일 때는 홈 화면이 열리는지, 주요 버튼이 동작하는지 정도만 확인해도 큰 문제가 없어 보일 수 있지만, 통합 앱에서는 프로파일이 늘어나면 테스트의 기준도 같이 바뀌어야 한다. 여러 앱 프로파일을 하나의 코드베이스에서 관리하면 공통 컴포넌트 하나를 수정했을 뿐인데 특정 프로파일의 초기 화면, 메뉴, 권한 요청, 라우팅이 깨질 수 있기 때문이다.
이럴 때 필요한 것이 프로파일 회귀 테스트다. 여기서 회귀 테스트는 예전에 되던 기능이 새 변경 이후에도 그대로 되는지 확인하는 테스트라고 보면 된다.
이 글에서는 React Native 통합 앱에서 profile registry, selectedProfiles, route guard, feature flag를 기준으로 어떤 테스트를 설계하면 좋은지 정리해본다.
이 글에서 다룰 문제
프로파일 기반 앱에서 회귀 테스트가 부족하면 다음과 같은 문제가 생긴다.
- 새 프로파일을 추가했는데 기존 프로파일의 첫 화면이 바뀐다.
- 지도 기능이 없는 앱에서 지도 탭이나 위치 권한 요청이 노출된다.
selectedProfiles로 단일 빌드는 되지만 실제 연결 UI 테스트 대상이 잘못 잡힌다.- 비활성 프로파일이 테스트 대상에 섞여 실패 로그가 불필요하게 늘어난다.
- 특정 앱만 실패했는데 로그가 흩어져 원인 분류가 늦어진다.
- 테스트 fixture에 실제 URL, API 키, 관리자 경로가 들어가 공개 위험이 생긴다.
처음에는 “빌드가 되면 괜찮겠지”라고 생각하기 쉽다. 하지만 빌드는 문법과 의존성 문제를 주로 잡아줄 뿐, 프로파일별 화면 정책까지 보장하지는 않는다. 그래서 통합 앱에서는 빌드 테스트와 UI 회귀 테스트를 분리해서 봐야 한다.
프로파일 회귀 테스트의 기준
프로파일 회귀 테스트는 모든 화면을 완벽하게 자동화하는 것이 목적이 아니라, 변경 영향이 큰 지점을 빠르게 확인하는 것이다.
| 테스트 영역 | 확인할 내용 | 실패 시 영향 |
|---|---|---|
profile registry |
필수 필드 누락, 중복 profileId, 비활성 상태 |
빌드 대상 해석 실패 |
selectedProfiles |
선택된 프로파일만 빌드/테스트되는지 | 엉뚱한 앱 빌드 또는 누락 |
initial route |
앱 시작 화면이 존재하는지 | 실행 직후 빈 화면 또는 크래시 |
route guard |
접근하면 안 되는 화면이 막히는지 | 잘못된 메뉴 노출 |
feature flag |
지도, 검색, 설정 기능 노출 기준 | 앱별 기능 정책 오류 |
permission flow |
필요 권한만 요청되는지 | 사용자 경험 악화, 심사 리스크 |
connected UI |
실제 기기/에뮬레이터에서 기본 화면 동작 | 런타임 오류 발견 |
처음부터 모든 항목을 자동화하기는 어렵다. 그렇다면 profile registry 검증, selectedProfiles 검증, 대표 프로파일 connected UI 테스트부터 시작하는 것이 좋다. 이 세 가지는 통합 앱에서 영향 범위가 넓고, 실패했을 때 원인을 비교적 빨리 좁힐 수 있다.
테스트 범위를 어떻게 나눌까
프로파일이 많아질수록 모든 앱을 매번 테스트하기는 어렵다. 그래서 테스트 범위를 나누는 기준이 필요하다.
| 범위 | 추천 시점 | 예시 |
|---|---|---|
| 단일 프로파일 | 특정 앱만 수정했을 때 | --profile sampleTourBusan |
| 같은 group | 공통 데이터 로더를 수정했을 때 | --group tour-regional |
| 대표 프로파일 | 공통 UI 또는 네비게이션 수정 시 | 관광 대표 1개, 파일 데이터 대표 1개 |
| 전체 프로파일 | 배포 전 또는 주기 점검 | --all |
| 제외 목록 반영 | 테스트 불가능/비활성 앱 관리 | exclusion config |
이 구조는 개발 속도와 안정성 사이의 균형을 잡기 위한 것이다. 로컬에서는 수정한 프로파일만 빠르게 확인하고, PR이나 배포 전에는 대표 프로파일 또는 group 단위로 넓혀가는 방식이 현실적이다.
selectedProfiles 테스트 예시
아래 코드는 실제 프로젝트에 사용했던 코드를 단순화한 예시다. 핵심은 profile, group, all 옵션을 받아 테스트 대상을 해석하고, 제외 목록을 반영하는 구조다.
// profile-test-scope.mjs
const profiles = [
{
profileId: 'sampleTourBusan',
applicationId: 'com.example.tour.busan',
group: 'tour',
enabled: true,
},
{
profileId: 'sampleFileData',
applicationId: 'com.example.filedata',
group: 'filedata',
enabled: true,
},
{
profileId: 'sampleLegacy',
applicationId: 'com.example.legacy',
group: 'legacy',
enabled: false,
},
];
const excludedApplicationIds = new Set(['com.example.legacy']);
function resolveTargets({profileId, group, all = false}) {
const enabled = profiles.filter((profile) => profile.enabled);
const selected = enabled.filter((profile) => {
if (all) return true;
if (profileId) return profile.profileId === profileId;
if (group) return profile.group === group;
return false;
});
return selected.filter((profile) => !excludedApplicationIds.has(profile.applicationId));
}
function assertTargets(targets) {
if (targets.length === 0) {
throw new Error('No test targets resolved. Check profileId, group, or exclusion config.');
}
}
const targets = resolveTargets({profileId: process.env.PROFILE_ID});
assertTargets(targets);
console.table(targets);
테스트 대상이 비어 있는데 성공으로 처리되면 “검증이 통과했다”고 착각할 수 있기 때문에, 대상이 없을 때 조용히 성공시키지 않는 것이 중요하다.
이런 상황은 처음 테스트 스크립트를 만들 때 특히 헷갈리기 쉽다. 실제로는 아무것도 검증하지 않았는데 CI 결과만 초록색으로 보일 수 있기 때문이다. 대상이 비어 있다면 명확한 실패로 처리하는 편이 안전하다.
connected UI 테스트에서 확인할 것
connected UI 테스트는 실제 기기나 에뮬레이터에서 앱을 실행해 기본 흐름을 확인하는 방식이다. 프로파일 기반 앱에서는 다음 항목을 최소 기준으로 잡을 수 있다.
- 앱이 설치되고 실행되는가?
- 첫 화면이
profile registry의initialRoute와 일치하는가? - 프로파일 이름이나 앱 제목이 올바르게 표시되는가?
feature flag에 맞는 탭과 메뉴만 보이는가?- 필요 없는 권한 요청이 뜨지 않는가?
- 빈 데이터나 네트워크 실패 상태에서 화면이 깨지지 않는가?
- 외부 링크나 개인정보 처리방침 링크가 안전한 예시 또는 실제 공개 URL로 연결되는가?
테스트 자동화가 어렵다면 스크린샷 캡처와 로그 저장만 먼저 해도 도움이 된다. 실패 시 어떤 프로파일에서 어떤 명령이 실행됐는지, 몇 번째 재시도에서 실패했는지, 실패 종류가 네트워크인지 UI인지 기록하면 원인 추적이 훨씬 쉬워진다.
실패 로그를 분류해야 하는 이유
통합 앱 회귀 테스트에서는 실패 원인이 다양하다. API 응답 지연, 네트워크 오류, 에뮬레이터 상태, 권한 팝업, 실제 UI 변경이 모두 테스트 실패처럼 보일 수 있다. 그래서 실패 로그를 적어도 아래처럼 분류하는 것이 좋다.
| 실패 종류 | 예시 | 대응 |
|---|---|---|
build failure |
컴파일 오류, flavor 누락 | registry와 Gradle 설정 확인 |
ui failure |
버튼 미노출, 라우트 오류 | 화면 조건과 feature flag 확인 |
permission failure |
권한 팝업으로 테스트 중단 | 권한 요청 시점 조정 |
api/network failure |
timeout, UnknownHost | mock, 재시도, 네트워크 분리 검토 |
device failure |
adb 연결 끊김 | 장비 상태와 테스트 환경 확인 |
이렇게 나누면 실패를 무조건 코드 문제로만 보지 않게 된다. 특히 네트워크 기반 화면이 많은 앱은 API 실패와 UI 회귀를 분리하지 않으면 불필요한 수정이 늘어날 수 있다.
테스트 fixture에서 민감 정보를 제거하기
테스트 데이터를 만들 때는 운영 데이터와 비밀값이 섞이지 않도록 조심해야 한다. 프로파일 테스트 fixture에는 앱 이름, profileId, group 정도만 두고, 실제 서버 URL이나 API 키는 넣지 않는 편이 안전하다.
| 넣어도 되는 값 | 피해야 할 값 |
|---|---|
예시 profileId |
실제 관리자 URL |
예시 applicationId |
API 키, 토큰 |
| 공개 가능한 앱 표시명 | 광고 ID, Firebase 설정값 |
group, engine |
keystore 경로와 비밀번호 |
feature flag |
사용자 식별자 |
추천 테스트 단계
처음부터 완벽한 테스트 시스템을 만들 필요는 없다. 아래 순서로 넓혀가면 부담을 줄일 수 있다.
profile registry필수 필드 검증을 추가한다.selectedProfiles대상 해석 테스트를 추가한다.route guard와feature flaghelper 단위 테스트를 작성한다.- 대표 프로파일 1~2개 connected UI 테스트를 붙인다.
- 실패 로그와 JSON 리포트를 남긴다.
- group 단위 테스트와 전체 테스트를 배포 전 단계로 확장한다.
- 테스트 제외 목록과 제외 사유를 별도 파일로 관리한다.
처음 자동화를 붙인다면 1~3단계부터 시작하는 것이 좋다. 특히 selectedProfiles 대상 해석 테스트는 비용이 낮고 효과가 좋은 편이다. 빌드 대상이 잘못 잡히는 문제를 초기에 잡아주기 때문이다.
자주 하는 실수
빌드 성공을 회귀 테스트 성공으로 보는 경우가 있다. 빌드는 중요하지만 첫 화면, 메뉴 노출, 권한 요청, 라우팅 정책까지 확인해주지는 않는다. 프로파일 기반 앱에서는 빌드 성공 이후에 화면 정책이 맞는지도 따로 확인해야 한다.
테스트 대상이 0개인데 성공 처리하는 경우도 있다. 이 경우 실제로는 아무것도 검증하지 않았는데 결과만 초록색으로 보일 수 있다. 대상이 비어 있다면 실패시키거나 최소한 명확한 경고를 남겨야 한다.
모든 실패를 UI 문제로 보는 것도 자주 생기는 실수다. API timeout이나 adb 연결 문제도 테스트 실패로 나타날 수 있다. 실패 로그를 분류해두면 괜히 화면 코드를 수정하는 일을 줄일 수 있다.
fixture에 실제 운영 정보를 넣는 경우도 조심해야 한다. 테스트 코드는 생각보다 자주 공유되고 문서에 붙는다. 공개 가능한 예시값을 쓰는 습관을 들이는 것이 좋다.
결론
React Native 통합 앱에서 프로파일 회귀 테스트는 선택 사항이 아니라 유지보수 비용을 줄이기 위한 안전장치다. 프로파일이 늘어날수록 공통 코드 변경이 어디까지 영향을 주는지 한눈에 알기 어렵기 때문이다.
좋은 시작점은 profile registry 검증, selectedProfiles 대상 해석 테스트, 대표 프로파일 connected UI 테스트다. 여기에 route guard와 feature flag 테스트를 붙이면 앱별 초기 화면, 메뉴, 권한, 라우팅 오류를 더 빨리 찾을 수 있다.
테스트는 처음부터 거창할 필요가 없다. 작은 검증을 꾸준히 쌓고, 실패 로그를 프로파일별로 남기고, 민감 정보를 fixture에서 제거하는 것부터 시작해보는 것이 좋다. 이런 기준이 있으면 새 프로파일을 추가할 때도 “어디까지 확인해야 하는지”가 훨씬 분명해진다.
참고 자료
- React Native Testing Library 관련 문서
- Android connected AndroidTest와 Gradle task 관련 문서
- Gradle project property와 product flavor 공식 문서
- 프로젝트 내부 profile registry, selectedProfiles, connected UI test 문서