자동 테스트는 여러 방식으로 앱 품질을 개선하는 데 도움이 됩니다. 예를 들어 유효성 검사를 실행하고, 회귀를 포착하고, 호환성을 확인하는 데 도움이 됩니다. 적절한 테스트 전략을 사용하면 자동 테스트를 활용하여 중요한 이점인 개발자 생산성에 집중할 수 있습니다.
팀은 체계적인 테스트 접근 방식과 인프라 개선사항을 함께 사용할 때 더 높은 수준의 생산성을 얻게 됩니다. 이렇게 하면 코드의 동작에 관한 적시적인 의견을 제공할 수 있습니다. 효과적인 테스트 전략은 다음을 실행합니다.
- 문제를 최대한 빨리 포착합니다.
- 실행 속도가 빠릅니다.
- 수정해야 할 사항이 있으면 이를 명확하게 표시합니다.
이 페이지에서는 구현할 테스트 유형, 테스트 실행 위치, 테스트 실행 빈도를 결정하는 데 도움이 됩니다.
테스트 피라미드
최신 애플리케이션에서 테스트를 크기별로 분류할 수 있습니다. 소규모 테스트는 코드의 일부분에만 집중하므로 빠르고 안정적입니다. 대규모 테스트는 범위가 넓고 유지 관리하기 어려운 더 복잡한 설정이 필요합니다. 하지만 대규모 테스트는 충실도*가 더 높고 한 번에 더 많은 문제를 발견할 수 있습니다.
*충실도란 테스트 런타임 환경과 프로덕션 환경의 유사성을 나타냅니다.
대부분의 앱에는 작은 테스트가 많이 있고 큰 테스트는 상대적으로 적습니다. 각 카테고리의 테스트 분포는 피라미드를 형성해야 합니다. 즉, 소규모 테스트가 많고 대규모 테스트가 적은 피라미드가 만들어져야 합니다.
버그 비용 최소화
좋은 테스트 전략은 개발자의 생산성을 극대화하는 동시에 버그를 찾는 비용을 최소화합니다.
비효율적인 전략의 예를 생각해 보세요. 여기서는 크기별 테스트 수가 피라미드로 구성되지 않습니다. 대규모 엔드 투 엔드 테스트가 너무 많고 구성요소 UI 테스트가 너무 적습니다.
이는 병합 전에 실행되는 테스트가 너무 적다는 의미입니다. 버그가 있는 경우 야간 또는 주간 종단간 테스트가 실행될 때까지 테스트에서 버그를 포착하지 못할 수 있습니다.
버그를 식별하고 수정하는 데 드는 비용과 테스트 작업을 더 작고 빈번한 테스트에 편향하는 것이 중요한 이유를 고려해야 합니다.
- 단위 테스트에서 버그를 포착하면 일반적으로 몇 분 안에 수정되므로 비용이 적습니다.
- 엔드 투 엔드 테스트에서는 동일한 버그를 발견하는 데 며칠이 걸릴 수 있습니다. 이로 인해 여러 팀원이 참여하게 되어 전반적인 생산성이 저하되고 출시가 지연될 수 있습니다. 이 버그의 비용이 더 높습니다.
하지만 비효율적인 테스트 전략이라도 전략이 없는 것보다는 낫습니다. 버그가 프로덕션에 반영되면 수정사항이 사용자 기기에 적용되기까지 오랜 시간이 걸립니다(일부 경우 몇 주가 걸림). 따라서 피드백 루프가 가장 길고 비용이 많이 듭니다.
확장 가능한 테스트 전략
테스트 피라미드는 전통적으로 다음 3가지 카테고리로 나뉩니다.
- 단위 테스트
- 통합 테스트
- 엔드 투 엔드 테스트
하지만 이러한 개념에는 정확한 정의가 없으므로 팀에서 5개 레이어를 사용하여 카테고리를 다르게 정의할 수 있습니다.
- 단위 테스트는 호스트 머신에서 실행되며 Android 프레임워크에 관한 종속 항목 없이 로직의 단일 기능 단위를 확인합니다.
- 예: 수학 함수에서 오프바이원 오류 확인
- 구성요소 테스트는 시스템의 다른 구성요소와 별개로 모듈 또는 구성요소의 기능이나 모양을 확인합니다. 단위 테스트와 달리 구성요소 테스트의 노출 영역은 개별 메서드 및 클래스보다 높은 추상화 수준까지 확장됩니다.
- 예: 맞춤 버튼의 스크린샷 테스트
- 기능 테스트는 두 개 이상의 독립적인 구성요소 또는 모듈의 상호작용을 확인합니다. 기능 테스트는 더 크고 복잡하며 일반적으로 기능 수준에서 실행됩니다.
- 예: 화면에서 상태 관리를 확인하는 UI 동작 테스트
- 애플리케이션 테스트는 배포 가능한 바이너리 형식으로 전체 애플리케이션의 기능을 확인합니다. 이러한 테스트는 디버그 가능한 바이너리(예: 테스트 후크를 포함할 수 있는 개발 빌드)를 테스트 중인 시스템으로 사용하는 대규모 통합 테스트입니다.
- 예: 폴더블, 현지화, 접근성 테스트에서 구성 변경사항을 확인하는 UI 동작 테스트
- 출시 후보 테스트는 출시 빌드의 기능을 확인합니다.
이는 애플리케이션 바이너리가 축소 및 최적화된다는 점을 제외하면 애플리케이션 테스트와 유사합니다. 이는 앱을 공개 사용자 계정 또는 공개 백엔드에 노출하지 않고 프로덕션에 최대한 가까운 환경에서 실행되는 대규모 엔드 투 엔드 통합 테스트입니다.
- 예: 중요한 사용자 여정, 성능 테스트
이 분류는 충실도, 시간, 범위, 격리 수준을 고려합니다. 여러 레이어에 서로 다른 유형의 테스트를 보유할 수 있습니다. 예를 들어 애플리케이션 테스트 영역에는 동작, 스크린샷, 성능 테스트가 포함될 수 있습니다.
범위 |
네트워크 액세스 |
실행 |
빌드 유형 |
수명 주기 |
|
---|---|---|---|---|---|
단위 |
최소한의 종속 항목이 있는 단일 메서드 또는 클래스 |
아니요 |
로컬 |
디버그 가능 |
병합 전 |
구성요소 |
모듈 또는 구성요소 수준 함께 수업하는 여러 수업 |
아니요 |
로컬 |
디버그 가능 |
병합 전 |
기능 |
지형지물 수준 다른 팀이 소유한 구성요소와 통합 |
모의 콘텐츠 |
로컬 |
디버그 가능 |
사전 병합 |
애플리케이션 |
애플리케이션 수준 다른 팀이 소유한 기능 또는 서비스와 통합 |
모의 |
에뮬레이터 |
디버그 가능 |
병합 전 |
출시 후보 |
애플리케이션 수준 다른 팀이 소유한 기능 또는 서비스와 통합 |
프로덕션 서버 |
에뮬레이터 |
축소된 출시 빌드 |
병합 후 |
테스트 카테고리 결정
일반적으로 팀에 적절한 수준의 의견을 제공할 수 있는 피라미드의 최하위 레이어를 고려해야 합니다.
예를 들어 이 기능의 구현(로그인 흐름의 UI)을 테스트하는 방법을 생각해 보세요. 테스트해야 하는 항목에 따라 다양한 카테고리를 선택합니다.
테스트 대상 |
테스트 대상에 대한 설명 |
시험 카테고리 |
테스트 유형의 예 |
---|---|---|---|
양식 검사기 로직 |
정규 표현식에 대해 이메일 주소를 확인하고 비밀번호 필드가 입력되었는지 확인하는 클래스입니다. 종속 항목이 없습니다. |
단위 테스트 |
|
로그인 양식 UI 동작 |
양식이 검증되었을 때만 사용 설정되는 버튼이 있는 양식 |
구성요소 테스트 |
Robolectric에서 실행되는 UI 동작 테스트 |
로그인 양식 UI 모양 |
UX 사양을 준수하는 양식 |
구성요소 테스트 |
|
인증 관리자와 통합 |
인증 관리자에게 사용자 인증 정보를 전송하고 다양한 오류가 포함될 수 있는 응답을 수신하는 UI입니다. |
기능 테스트 |
|
로그인 대화상자 |
로그인 버튼을 누르면 로그인 양식이 표시되는 화면입니다. |
애플리케이션 테스트 |
Robolectric에서 실행되는 UI 동작 테스트 |
중요한 사용자 여정: 로그인 |
스테이징 서버에 테스트 계정을 사용하는 전체 로그인 흐름 |
출시 후보 버전 |
기기에서 실행되는 엔드 투 엔드 Compose UI 동작 테스트 |
경우에 따라 특정 카테고리에 속하는지 또는 다른 카테고리에 속하는지 여부가 주관적일 수 있습니다. 인프라 비용, 불안정성, 긴 테스트 시간 등 테스트가 위 또는 아래로 이동하는 다른 이유가 있을 수 있습니다.
테스트 카테고리가 테스트 유형을 지정하지 않으며 모든 기능을 모든 카테고리에서 테스트할 필요는 없습니다.
수동 테스트를 테스트 전략의 일부로 포함할 수도 있습니다. 일반적으로 QA팀에서 출시 후보 테스트를 실행하지만 다른 단계에도 참여할 수 있습니다. 예를 들어 스크립트 없이 기능의 버그에 대한 탐색적 테스트를 들 수 있습니다.
테스트 인프라
테스트 전략은 개발자가 테스트를 지속적으로 실행하고 모든 테스트가 통과하도록 보장하는 규칙을 적용하는 데 도움이 되는 인프라와 도구로 지원되어야 합니다.
테스트를 범위별로 분류하여 어떤 테스트를 언제 어디서 실행할지 정의할 수 있습니다. 예를 들어 5층 모델은 다음과 같습니다.
카테고리 |
환경 (위치) |
트리거 (시점) |
---|---|---|
단위 |
[로컬][4] |
모든 커밋 |
구성요소 |
로컬 |
모든 커밋 |
기능 |
로컬 및 에뮬레이터 |
병합 전 또는 변경사항을 제출하기 전 |
애플리케이션 |
로컬, 에뮬레이터, 휴대전화 1대, 폴더블 1대 |
병합 후, 변경사항 병합 또는 제출 후 |
출시 후보 |
휴대전화 8종, 폴더블 1종, 태블릿 1종 |
발표 전 |
- 단위 및 구성요소 테스트는 영향을 받는 모듈에 대해서만 새 커밋마다 지속적 통합 시스템에서 실행됩니다.
- 변경사항을 병합하거나 제출하기 전에 모든 단위, 구성요소, 기능 테스트가 실행됩니다.
- 애플리케이션 테스트는 병합 후에 실행됩니다.
- 출시 후보 테스트는 스마트폰, 폴더블, 태블릿에서 매일 밤 실행됩니다.
- 출시 전에 출시 후보 테스트가 다수의 기기에서 실행됩니다.
이 규칙은 테스트 수가 생산성에 영향을 미치면 시간이 지남에 따라 변경될 수 있습니다. 예를 들어 테스트를 야간 주기로 전환하면 CI 빌드 및 테스트 시간이 줄어들 수 있지만 의견 루프가 길어질 수도 있습니다.