
출처: https://medium.com/better-programming/the-test-pyramid-80d77535573
이번에 Appium을 사용 해보다가 Jest 테스트 코드와 비슷하게 생겼다는 걸 느낄 수 있었다.
예를 들어:
A 버튼을 누르면 B Field에 "TEST"라는 값이 입력되는가?
이런 시나리오는 Jest로도, Appium으로도 테스트할 수 있다. 그렇다면 둘의 차이는 무엇일까?
유닛 테스트: 개별 함수/컴포넌트의 로직
통합 테스트: 여러 컴포넌트의 상호작용
E2E 테스트: 전체 시스템의 사용자 시나리오
it('A 버튼을 누르면 B Field에 "TEST"가 입력된다', () => {
render(<MyComponent />);
const button = screen.getByRole('button', { name: 'A' });
fireEvent.click(button); // 시뮬레이션된 클릭
const field = screen.getByRole('textbox', { name: 'B' });
expect(field).toHaveValue('TEST'); // JSDOM에서 확인
});
이 테스트가 놓치는 것들:
it('A 버튼을 누르면 B Field에 "TEST"가 입력된다', async () => {
const button = await driver.$('~button-a'); // 실제 앱에서 찾기
await button.click(); // 실제 디바이스에서 터치
const field = await driver.$('~field-b');
const value = await field.getText(); // 실제 렌더링된 값
expect(value).toBe('TEST');
});
이 테스트가 추가로 검증하는 것들:
Jest로는 발견 못하지만 E2E 테스트로 발견하는 버그들:
Appium, Playwright, Cypress, Selenium은 모두 E2E 테스트 도구다.
차이는 "어떤 환경을 테스트하느냐"만 다르다:
Playwright
├─ 웹 브라우저 (Chromium, Firefox, WebKit)
└─ 데스크톱/모바일 웹
Cypress
└─ 웹 브라우저 (Chrome, Firefox, Edge)
Selenium
└─ 웹 브라우저 (거의 모든 브라우저)
Appium
├─ 네이티브 모바일 앱 (iOS, Android)
├─ 하이브리드 앱
└─ 모바일 웹
실제 환경에서 실행
사용자 시나리오 테스트
// Playwright
await page.click('button');
await page.fill('input', 'test');
// Appium
await driver.$('button').click();
await driver.$('input').setValue('test');
/\
/E2E\ ← 적은 수, 핵심 시나리오만
/------\
/통합 테스트\ ← 중간 수, 주요 기능 조합
/----------\
/ 유닛 테스트 \ ← 많은 수, 모든 로직 커버
/--------------\
유닛 테스트 (많이)
통합 테스트 (적당히)
E2E 테스트 (소수 정예)
웹 프로젝트 → Playwright/Cypress
React Native/Flutter → Appium
웹 + 앱 → Playwright(웹) + Appium(앱)
Jest (유닛/통합): 코드 로직이 의도대로 작동하는가?
E2E 테스트: 실제 사용자 환경에서 제대로 작동하는가?
둘 다 필요하다. 유닛 테스트로 빠르게 로직을 검증하고, E2E 테스트로 실제 환경에서의 동작을 보장하는 것이 이상적인 전략이다.
코드상으로 문제가 없어도 실제 디바이스에서는 문제가 생길 수 있다. 그래서 두 종류의 테스트 모두 중요하다.