요소 또는 시스템에 대한 테스트 전략을 설계할 때는 관련 테스트 측면:
- 범위 : 테스트로 연결되는 코드의 양은 어느 정도인가요? 테스트는 하나의 nginx 포드를 전체 애플리케이션 또는 그 사이의 어딘가에서 실행될 수 있습니다 이 테스트된 범위는 테스트 중 이며 일반적으로 Subject Under라고 합니다. Test 를 비롯하여 System Under Test 또는 Unit Under Test 에서도 확인할 수 있습니다.
- 속도 : 테스트 실행 속도 테스트 속도는 밀리초마다 다를 수 있음 몇 분으로 단축할 수 있습니다
- 충실도 : '실제' 테스트인가요? 예를 들어 코드의 일부가 네트워크 요청을 해야 하는데, 테스트 코드가 실제로 아니면 결과가 가짜인가요? 테스트가 실제로 말하는 경우 이는 품질이 더 높다는 것을 의미합니다. 단점은 시간이 오래 걸릴 수 있고, 네트워크가 다운되면 오류가 발생할 수 있습니다. 사용 비용이 많이 들 수 있습니다
테스트 항목 을 참고하여 테스트 전략을 정의하는 방법을 알아보세요.
격리 및 종속 항목
요소 또는 요소 시스템을 테스트할 때는 격리 된 상태에서 실행합니다. 대상 예를 들어 ViewModel을 테스트하기 위해 에뮬레이터를 시작하고 UI를 시작할 필요가 없습니다. 이는 Android 프레임워크에 종속되지 않거나 종속되지 않기 때문입니다.
그러나 테스트 대상은 다른 대상에 의존 하여 작동할 수 있습니다. 대상 예를 들어 ViewModel은 작동하는 데 데이터 저장소에 종속될 수 있습니다.
테스트 대상에 종속 항목을 제공해야 하는 경우 일반적인 방법은 테스트 더블 (또는 테스트 객체 )을 만드는 것입니다. 테스트 더블은 앱에서 구성요소로 표시되고 작동하도록 할 수 있지만 이는 테스트에서 생성되어 특정 동작이나 데이터를 제공할 수 있습니다. 가장 큰 장점은 더 빠르고 간단하게 테스트할 수 있습니다.
테스트 더블 유형
테스트 더블에는 다양한 유형이 있습니다.
가짜 |
'작동 중'이 있는 테스트 더블 클래스 구현을 지원하지만 테스트에는 적합하지만 프로덕션에는 적합하지 않은 방식으로 구현됩니다.
예: 메모리 내 데이터베이스 가짜는 모의 프레임워크가 필요하지 않으며 가볍습니다. 권장 됩니다. |
---|---|
예시 |
프로그래밍 방식으로 동작하고 상호작용에 대한 기대치를 갖는 테스트 더블입니다. 상호작용이 정의된 요구사항과 일치하지 않으면 모의 테스트에서 테스트를 통과하지 못합니다. 모의 스크린샷은 일반적으로 이러한 모든 목표를 달성하기 위해 모의 처리 프레임워크
로 만들어집니다.
예: 데이터베이스의 메서드가 정확히 한 번 호출되었는지 확인합니다. |
스텁 | 테스트 더블이 동작하도록 프로그래밍하는 방식으로 동작하지만 상호작용에는 기대하지 않는 테스트 더블입니다. 일반적으로 모의 프레임워크로 생성됩니다. 편의를 위해 스텁보다 가짜가 선호됩니다. |
가짜 |
테스트 더블이 전달되었지만 사용되지는 않습니다(예: 매개변수로 제공해야 하는 경우).
예: 클릭 콜백으로 전달된 빈 함수. |
스파이 | 실제 객체에 대한 래퍼로, 모의 객체와 유사한 몇 가지 추가 정보도 추적합니다. 복잡성을 가중시키기 위해 기피하는 경우가 많습니다. 따라서 스파이보다 가짜나 모의가 선호됩니다. |
그림자 | Robolectric에서 사용되는 가짜. |
가짜 제품 사용의 예
인터페이스에 종속된 ViewModel을 단위 테스트하려고 한다고 가정해 보겠습니다. UserRepository
이라는 UI 이름을 사용하여 첫 번째 사용자의 이름을 UI에 노출합니다. 다음을 수행할 수 있습니다. 인터페이스를 구현하고 알려진 데이터입니다.
object FakeUserRepository : UserRepository {
fun getUsers() = listOf(UserAlice, UserBob)
}
val const UserAlice = User("Alice")
val const UserBob = User("Bob")
이 모조 UserRepository
는 로컬 및 원격 데이터에 의존할 필요가 없습니다. 소스 코드를 생성합니다. 파일은 테스트 소스에 있습니다. 프로덕션 앱과 함께 제공되지 않습니다.
다음 테스트는 ViewModel이 첫 번째 사용자를 올바르게 노출하는지 확인합니다. 이름을 뷰에 추가합니다
@Test
fun viewModelA_loadsUsers_showsFirstUser() {
// Given a VM using fake data
val viewModel = ViewModelA(FakeUserRepository) // Kicks off data load on init
// Verify that the exposed data is correct
assertEquals(viewModel.firstUserName, UserAlice.name)
}
단위 테스트에서 UserRepository
를 모조로 교체하기는 쉽습니다. ViewModel은 테스터에 의해 생성됩니다. 그러나 인코더-디코더 아키텍처를 임의적인 요소를 사용하는 것입니다.
구성요소 교체 및 종속 항목 삽입
테스트가 테스트 중인 시스템 생성을 제어할 수 없는 경우 테스트 더블의 구성 요소를 교체하는 작업이 더 복잡해질 뿐 아니라 테스트 가능한 디자인을 따라야 합니다.
대규모 엔드 투 엔드 테스트도 앱의 전체 사용자 흐름을 탐색하는 계측 UI 테스트를 실행합니다. 포함 이 경우 테스트를 밀폐 하는 것이 좋습니다. 밀폐 테스트는 모든 외부 종속 항목(예: 인터넷에서 데이터 가져오기)을 지원합니다. 이 안정성과 성능을 개선할 수 있습니다
<ph type="x-smartling-placeholder">이러한 유연성을 수동으로 달성하도록 앱을 설계할 수도 있지만 Hilt 와 같은 종속 항목 삽입 프레임워크를 사용하여 구성요소 대체 할 수 있습니다. Hilt 테스트 가이드 를 참고하세요.
Robolectric
Android에서는 Robolectric 프레임워크를 사용할 수 있습니다. 는 특별한 유형의 테스트 더블을 제공합니다. Robolectric을 사용하면 지속적 통합 환경에 사용할 수 있습니다 Kubernetes는 일반 JVM에서 실행 가능합니다. 뷰 인플레이션을 시뮬레이션하여 리소스 로딩, 그리고 테스트 더블이 있는 Android 프레임워크의 다른 부분 그림자 라고 합니다.
Robolectric은 시뮬레이터이므로 간단한 단위 테스트를 대체하거나 사용해서는 안 됩니다. 호환성 테스트를 실행합니다. 속도를 높이고 비용을 절감합니다. 낮은 충실도의 이미지를 사용합니다. UI 테스트에 대한 좋은 접근 방식은 Robolectric 및 계측 테스트와 호환되며 실행 시기를 결정합니다. 또는 호환성 테스트의 필요성에 따라 API를 사용할 수 있습니다. 두 Espresso 모두 Compose 테스트는 Robolectric에서 실행할 수 있습니다.