깨알 개념/Android

[Android] Unit Testing - 기초

interfacer_han 2024. 7. 8. 11:25

#1 이전 글

#1-1 Unit Testing 개요

 

[Android] Unit Testing - 개요와 환경 설정

#1 안드로이드 앱 테스트#1-1 안드로이드 앱 테스트의 종류먼저, 여기에 있는 구글 공식 문서에서 안드로이드 앱 테스트에 대한 개요를 읽으면 좋다. 해당 구글 공식 문서에서 복사해온 위의 그림

kenel.tistory.com

위 링크에 있는 이전 게시글에 이어서, 실제 안드로이드 프로젝트를 만들어 기초적인 안드로이드 Unit Testing을 수행해본다.

 

#1-2 환경 설정 (build.gradle 등)

이전 게시글의 #3을 토대로 본 게시글에 나오는 안드로이드 프로젝트의 Gradle, AGP, JDK의 버전 설정 및 build.gradle 설정을 진행한다. 이전 게시글의 build.gradle과 달리, 본 게시글에서는 Unit Testing에 사용되지 않는 build.gradle의 plugins { ... }, buildFeatures { ... }, dependencies { ... }의 일부 요소를 제거했다. 이는  코드 다이어트를 위한 개인적인 제거이기 때문에, 이 글은 보는 사람은 제거 없이 그냥 복사 및 붙여넣기해도 된다.

 

#2 Unit Testing을 적용할 샘플 앱

전체 소스 코드는 본 게시글의 #5에 있다.

 

#2-1 interface Calculation

interface Calculation {

    fun sum(operand1: Int, operand2: Int): Int

    fun multiply(operand1: Int, operand2: Int): Int

    fun sumAndSquare(operand1: Int, operand2: Int): Int
}

Unit Test를 진행할 클래스가 상속받을 인터페이스다.

 

#2-2 class MyCalculation : Calculation

class MyCalculation : Calculation {

    override fun sum(operand1: Int, operand2: Int): Int {
        return operand1 + operand2
    }

    override fun multiply(operand1: Int, operand2: Int): Int {
        return operand1 * operand2
    }

    override fun sumAndSquare(operand1: Int, operand2: Int): Int {
        val sum = sum(operand1, operand2)
        return multiply(sum, sum)
    }
}

Unit Test를 진행할 클래스다.

 

#3 Unit Testing

#3-1 테스트 클래스 간편하게 만들기

클래스 이름에 우클릭 후 [Generate...] 클릭

 

[Test...] 클릭

 

Create Test 창에서 Destination pacakge 선택 버튼 클릭

 

MyCalculation 클래스의 함수들은 단순히 수학적 계산만 수행하므로, 이러한 클래스의 테스트를 안드로이드 에뮬레이터에서 실행할 필요가 없다. 따라서 Local unit test에 속하는 unitTest 디렉토리를 선택한다 (Instrumented test도 Unit Test라는 범주에 속하지만, 안드로이드 에뮬레이터를 사용한다는 점에서 온전한(?) Unit Test는 아니기에 이렇게 나눠놓았다 보다).

 

OK 버튼 클릭

 

이렇게 테스트 클래스가 생성된다. 물론, 패키지 폴더에 우클릭하여 직접 클래스를 만들어도 상관없다.

 

#3-2 테스트 클래스의 내용 작성

import com.google.common.truth.Truth
import org.junit.Before
import org.junit.Test

class MyCalculationTest {
    private lateinit var myCalculation: MyCalculation

    @Before
    fun setUp() {
        myCalculation = MyCalculation()
    }

    @Test
    fun sum_given77And777_return854() { // subjectUnderTest_actionOrInput_resultState 규칙으로 함수 명명함
        val result = myCalculation.sum(77, 777)
        Truth.assertThat(result).isEqualTo(/* expected = */ 854)
    }

    @Test
    fun multiply_given3And4_return12() {
        val result = myCalculation.multiply(3, 4)
        Truth.assertThat(result).isEqualTo(/* expected = */ 12)
    }

    @Test
    fun sumAndSqaure_given9And5_return196() {
        val result = myCalculation.sumAndSquare(9, 5)
        Truth.assertThat(result).isEqualTo(/* expected = */ 196)
    }
}

@Before은 init { ... }과 비슷한 개념이라고 보면 된다. @After도 존재하는데, 이는 @Before과 반대로 테스트 종료 직전에 수행되는 코드의 모임이다. 각 테스트의 항목은 @Test 어노테이션이 붙은 메소드의 형태로 구현된다. 그리고 메소드의 이름은 subjectUnderTest_actionOrInput_resultState 작명 규칙으로 짓는 것이 관례라고 한다. assertThat() 함수는 테스트의 성공 혹은 실패를 결정하는 메소드다. 이 assertThat() 메소드는 여러 테스트 라이브러리가 동일한 이름의 메소드로서 지니고 있다. 나는 Truth 라이브러리의 assertThat()를 사용했다.

 

#3 작동 확인

메소드 옆에 뜨는 초록색 재생 버튼 클릭

 

[Run] 클릭

 

성공했다. 메소드 뿐만 아니라 클래스 이름 옆에도 재생버튼이 있다. 이는 클래스 내의 모든 @Test 메소드의 테스트를 한 번에 수행한다.

 

#4 완성된 앱

 

android-practice/unit-test/UnitTestingBasics at master · Kanmanemone/android-practice

Contribute to Kanmanemone/android-practice development by creating an account on GitHub.

github.com