Android

안드로이드 [Kotlin] - 안드로이드 테스트 자동화

🤖 Play with Android 🤖 2022. 11. 27. 21:13
728x90


  • 안드로이드에서 기능을 작성하면 필연적으로 기능의 테스트를 수행해야 한다.
  • 이는 애뮬레이터나 단말기에서 앱을 실행하고 구현한 기능을 이것저것 동작해보며 내가 기대하는 동작과 일치하는지 확인하는 것이다.

 

테스트 유형

  • 기능 테스트 : 앱이 제대로 기능을 수행하는지 확인
  • 성능 테스트 : 앱이 빠르고 효율적으로 수행하는지 확인
  • 접근성 테스트 : 접근성 서비스와 잘 연동되는지 확인
  • 호환성 테스트 : 모든 기기와 API 수준에서 잘 작동하는지 확인

 

수동 테스트

  • 테스트 자동화에 대해 알지 않아도 즉 초보라도 쉽게 수행할 수 있다.
  • 하지만 앱의 기능이 많아지고 구조가 복잡해지면 점점 빌드시간이 증가하고, 코드를 수정할 때마다 앱의 모든 기능을 수동으로 일일이 확인하는 것은 비효율적이다.

 

자동 테스트

  • 사람이 수동으로 일일히 하는 테스트를 컴퓨터가 자동으로 하게 해주는 것이 테스트 자동화이다.
  • 테스트 자동화를 적용하면 기능을 개발할 때마다 수동으로 일일이 테스트할 때보다 개발 시간이 감소되며, 비용 절감 효과가 있다.
  • 또한 개발자가 코드를 작성할 때 자동 테스트가 되도록 구조를 고려하기 때문에 보다 자연스럽게 프로그램이 견고한 구조로 작성된다.

 

 

자동 테스트의 분류

구글의 분류

 

  • 구글은 안드로이드 자동 테스트를 위 그림과 같이 단위 테스트(Unit Test), 통합 테스트(Integration Test), 종단간 테스트(End to end Test), 앱(App)으로 분리하고 있다.
  • 유닛 테스트(Unit Test)에서 종단간 테스트(End to end) 테스트로 갈수록 각 테스트의 충실도는 증가하지만 실행시간과 유지보수 및 디버깅에 드는 노력 역시 증가한다.

 

단위 테스트 (Unit Test)

  • 단위 테스트는 앱의 메서드 또는 클래스와 같은 작은 단위의 기능을 검증한다.
  • 테스트의 범위가 작기 때문에 비교적 작성이 수월하고 테스트 속도도 빠르다.

안드로이드의 단위 테스트에는 두 가지가 존재한다.

  • 로컬 단위 테스트 (Local Unit Test)
    • 안드로이드 프레임워크 (Android Framework)에 의존하지 않고 로컬 JVM에서 실행되는 테스트
    • 실제 기기나 애뮬레이터를 사용하지 않으므로 테스트 속도가 빠르다는 특징이 있다.
  • 계측 단위 테스트 (Instrumented Unit Test)
    • Android Framework에 의존하는 기능을 검증하는 단위 테스트
    • 실제 단말기 혹은 에뮬레이터에서 실행해야 하기 때문에 테스트 속도가 비교적 느리다.

 

 

통합 테스트 (Integration Test)

  • 서로 다른 모듈 또는 클래스 간의 상호작용이 정상적으로 기능하는지를 검증한다.
  • 단위 테스트로 각각 모듈의 기능이 정상적으로 동작하는 것을 검증했을지라도 동시에 여러 모듈을 동작시켰을 때는 비정상적으로 동작할 수 있다.

 

 

종단간 테스트 (End-to-end Test)

  • 앱의 전체 화면 또는 여러 모듈에 걸친 사용자 흐름(User Flow)과 같은 큰 부분에 대한 기능 검증을 수행하는 테스트
  • UI 테스트라 부르기도 한다. 

 

 

테스트 기본 원칙 (F.I.R.S.T)

  • Fast : 단위 테스트는 빨라야 한다.
  • Isolated : 테스트가 다른 테스트 케이스에 의존하지 않아야 한다.
  • Repeatable : 테스트는 실행할 때마다 같은 결과를 만들어야 한다.
  • Self-Validating : 테스트 결과는 성공이거나 실패여야 한다. 결과에 대한 해석이 필요해서는 안된다.
  • Timely : 단위 테스트는 기능이 출시된 후에도 언제든 작성할 수 있지만, 적절한 시점은 프로덕션 코드를 구현하고 있는 와중에 테스트 코드를 작성하는 것이다.

 

 

테스트 코드 작성 스타일

Given - When - Then 스타일

  • Given : 어떠한 상태 하에서
  • When : 어떠한 기능을 실행하면
  • Then : 어떠한 결과가 나와야 한다.
@Test
fun x1_multiplyBy2() {
    // Given
    val x = 1
    
    // When
    val result = Utils.mutipleBy2(x)
    
    // Then
    assertEquals(2, result)
}

 

 

 

테스트 대상 항목

구글에서 제안하는 안드로이드가 앱의 주된 테스트 항목은 다음과 같다.

  • 단위 테스트 대상
    • ViewModel 또는 Presenter
    • 데이터 레이어 (Data Layer)
    • 유스 케이스 (Use Case)
    • 값을 계산하는 유틸리티 클래스
  • 엣지 케이스
    • 음수, 0 및 경계 조건을 사용하는 수학 연산
    • 가능한 모든 네트워크 연결 오류
    • 형식이 잘못된 JSON과 같은 손상된 데이터
    • 파일 저장 시 스토리지가 가득 찬 상황
    • 프로세스 중간에 다시 생성된 개체 (ex: 장치가 회전할 때의 Activity)
  • UI 테스트
    • 스크린 UI
    • 유저 플로우
    • 내비게이션
  • 테스트 제외 대상
    • 프레임워크 자체의 동작
    • 액티비티(Activity), 프레그먼트(Fragement), 서비스(Service)에는 테스트가 필요한 로직을 가능한 배치하지 않는다.

 

 

테스트 라이브러리

Testing Framework

  • Juint4 : Java의 단위 테스트 코드를 작성하기 위해 만들어진 프레임워크로 Jetpack Test 라이브러리는 Juint4를 기준으로 만들어져 있다. 최선 버전은 Junit5이나, 안드로이드를 완벽히 지원하지 않는다.
  • Kotest : 코틀린(Kotlin)의 단위 테스트 코드를 작성하기 위해 만들어진 프레임워크
  • Robolectric : JVM 만으로 안드로이드 프레임워크를 테스트하기 위해 만들어진 프레임워크

 

Testing Assertion

Junit의 Assertion의 부족한 표현력을 보완해주는 라이브러리

  • AssertJ
  • Truth
  • Hancrest
// Juint
assertTrue(notificationText.contains("testuser@google.com"));

// AssertJ, Truth
assertThat(notificationText).contains("testuser@google.com"));

// Hamcrest
assertThat(notificationText, containsString("testuser@google.com"));

 

Mocking

  • Mockito : Java 테스트를 위한 Mocking 라이브러리
  • MockK : Kotlin 테스트를 위한 Mocking 라이브러리

 

UI Testing

  • Espresso : 단일 안드로이드 앱의 UI를 테스트하는 프레임워크 (구글 제공)
  • Kaspresso : KasperskyLab에서 제작한 안드로이드 앱 UI 테스트 프레임워크
  • Appium : 안드로이드와 ios를 모두 테스트할 수 있는 UI 테스트 프레임워크
  • UI Automator : 복수 앱 간의 UI 기능을 테스트하는 프레임워크 (구글 제공)

 

 

CI/CD

프로덕트의 빌드 과정

  • 연관된 의존성 다운로드
  • 소스 코드를 바이너리 코드로 컴파일
  • 바이너리 코드를 링크하여 실행 가능한 파일로 패키징
  • 테스트 수행
  • 프로덕션 시스템에 배포

코드 변경이 별로 없는 프로덕션이라면 빌드 과정을 개발자가 직접 수행해도 상관없지만 코드 변경이 자주 일어나고 여러 명의 개발자가 같은 기능을 구현하는데 연관되어 있다면 어떤 순서로 빌드를 실행해야 하는지도 알기 어렵다.

 

지속적 통합 : Continuous Integration(CI)

  • 개발자가 코드를 작성하고 저장소에 커밋하면 자동으로 컴파일과 테스트를 수행

지속적 제공 : Continuous Delivery(CD)

  • CI가 완료되어 배포할 수 있는 상태의 빌드 결과물을 저장소에 업로드하는 것

지속적 배포 : Continuous Deployment(CD)

  • 지속적 제공 과정이 완료된 결과물을 최종 사용자가 사용할 수 있는 환경까지 자동으로 배포하는 솔루션

CI/CD는 개발자는 빌드와 배포에는 신경 쓰지 않고 코드 작성에만 집중할 수 있게 도와준다.