로컬 단위 테스트 빌드

로컬 테스트는 Android가 아닌 자체 워크스테이션에서 직접 실행됩니다. 실행할 수 있습니다 따라서 로컬 JVM (Java Virtual Machine)을 사용하고 테스트를 실행할 수 있습니다. 로컬 테스트를 사용하면 앱의 로직을 더 빠르게 평가할 수 있습니다. 그러나 Android 프레임워크와 상호작용할 수 없으므로 실행할 수 있는 테스트 유형에 제한이 있습니다.

단위 테스트는 코드의 작은 섹션인 테스트 대상 단위의 동작을 확인합니다. 이 작업은 해당 코드를 실행하고 결과를 확인하여 수행합니다.

단위 테스트는 일반적으로 간단하지만, 단위 테스트가 더 이상 테스트 가능성을 염두에 두고 설계되지 않았습니다.

  • 인증하려는 코드는 테스트에서 액세스할 수 있어야 합니다. 예를 들어 비공개 메서드는 직접 테스트할 수 없습니다. 대신 공개 API를 사용하여 클래스를 테스트합니다.
  • 단위 테스트를 격리된 상태로 실행하려면 테스트 대상 단위의 종속 항목을 가짜 또는 기타 테스트 더블과 같이 개발자가 제어하는 구성요소로 대체해야 합니다. 이는 코드가 종속 항목이나 Android 프레임워크입니다.

Android의 일반적인 단위 테스트 전략에 관해 알아보려면 테스트할 항목을 참고하세요.

로컬 테스트 위치

기본적으로 로컬 단위 테스트의 소스 파일은 module-name/src/test/에 배치됩니다. 새 디렉터리를 만들 때 이 디렉터리는 이미 존재합니다. 프로젝트를 빌드합니다.

테스트 종속 항목 추가

또한 프로젝트에서 테스트 종속 항목을 구성하여 JUnit 테스트 프레임워크에서 제공하는 표준 API를 사용합니다.

이렇게 하려면 앱 모듈의 build.gradle 파일을 열고 다음을 지정합니다. 라이브러리를 종속 항목으로 만듭니다 testImplementation 함수를 사용하여 다음을 나타냅니다. 애플리케이션이 아닌 로컬 테스트 소스 세트에 적용됩니다.

dependencies {
  // Required -- JUnit 4 framework
  testImplementation "junit:junit:$jUnitVersion"
  // Optional -- Robolectric environment
  testImplementation "androidx.test:core:$androidXTestVersion"
  // Optional -- Mockito framework
  testImplementation "org.mockito:mockito-core:$mockitoVersion"
  // Optional -- mockito-kotlin
  testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
  // Optional -- Mockk framework
  testImplementation "io.mockk:mockk:$mockkVersion"
}

로컬 단위 테스트 클래스 만들기

로컬 단위 테스트 클래스는 JUnit 4 테스트 클래스로 작성합니다.

이렇게 하려면 하나 이상의 테스트 메서드가 포함된 클래스를 만듭니다(일반적으로 module-name/src/test/에서). 테스트 메서드는 @Test 주석으로 시작하고 에는 구성 요소의 단일 측면을 실행하고 확인하는 코드가 포함되어 있습니다. 지정할 수 있습니다

다음 예는 로컬 단위 테스트 클래스를 구현하는 방법을 보여줍니다. 이 테스트 메서드가 emailValidator_correctEmailSimple_returnsTrue()인증을 시도하고 isValidEmail(): 앱 내의 메서드입니다. 테스트 함수는 isValidEmail()도 true를 반환합니다.

Kotlin


import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test

class EmailValidatorTest {
  @Test fun emailValidator_CorrectEmailSimple_ReturnsTrue() {
    assertTrue(EmailValidator.isValidEmail("name@email.com"))
  }

}

자바


import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

class EmailValidatorTest {
  @Test
  public void emailValidator_CorrectEmailSimple_ReturnsTrue() {
    assertTrue(EmailValidator.isValidEmail("name@email.com"));
  }
}

앱의 구성요소가 예상 결과를 반환하는지 평가하며 읽을 수 있는 테스트를 만들어야 합니다. 다음과 같은 어설션 라이브러리를 사용하는 것이 좋습니다. junit.Assert, Hamcrest 또는 진실. 위 스니펫은 junit.Assert를 사용하는 방법의 예입니다.

모의 Android 라이브러리

로컬 단위 테스트를 실행하면 Android Gradle 플러그인에 모든 API가 포함된 라이브러리를 사용자 인증 정보를 제공합니다 라이브러리에는 모든 공개 메서드와 해당 API의 클래스를 지원하지만 메서드 내부의 코드는 제거되었습니다. 해당되는 경우 의 메서드가 액세스되면 테스트에서 예외가 발생합니다.

이렇게 하면 Android에서 클래스를 참조할 때 로컬 테스트를 빌드할 수 있습니다. 프레임워크(예: Context) 더 중요한 점은 Android 클래스에서 모의 프레임워크를 사용할 수 있다는 것입니다.

Android 종속 항목 모의 처리

일반적인 문제는 클래스가 문자열 리소스를 사용하고 있는 것을 발견하는 것입니다. 다음과 같은 작업을 할 수 있습니다. Context에서 getString() 메서드를 호출하여 문자열 리소스를 가져옵니다. 클래스에 대해 자세히 알아보세요. 그러나 Context는 Android 프레임워크에 속하므로 로컬 테스트에서는 이를 사용할 수 없습니다. getString() 호출은 다음과 같습니다. 이동했으나 항상 실용적이지는 않습니다. 해결 방법은 getString() 메서드가 호출될 때 항상 동일한 값을 반환하는 Context의 모의 또는 스텁을 만드는 것입니다.

모의 Android 라이브러리와 Mockito 또는 MockK와 같은 모의 프레임워크를 사용하면 단위 테스트에서 Android 클래스의 모의 동작을 프로그래밍할 수 있습니다.

Mockito를 사용하여 로컬 단위 테스트에 모의 객체를 추가하려면 다음을 따르세요. 프로그래밍 모델:

  1. 테스트 환경 설정에 설명된 대로 Mockito 라이브러리 종속 항목을 build.gradle 파일에 포함합니다.
  2. 단위 테스트 클래스 정의의 시작 부분에 @RunWith(MockitoJUnitRunner.class) 주석 이 주석은 프레임워크 사용이 올바르고 모의 객체의 초기화를 단순화하는지 검증하도록 Mockito 테스트 실행기에 알립니다.
  3. Android 종속 항목의 모의 객체를 만들려면 @Mock 주석을 추가합니다. 를 입력합니다.
  4. 종속 항목의 동작을 스텁하려면 조건을 지정하고 when()thenReturn()를 사용하여 조건이 충족될 때의 반환 값 메서드를 참조하세요.

다음 예는 모의 테스트를 사용하는 단위 테스트를 만드는 방법을 보여줍니다. Mockito-Kotlin으로 만든 Kotlin의 Context 객체입니다.

import android.content.Context
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock

private const val FAKE_STRING = "HELLO WORLD"

@RunWith(MockitoJUnitRunner::class)
class MockedContextTest {

  @Mock
  private lateinit var mockContext: Context

  @Test
  fun readStringFromContext_LocalizedString() {
    // Given a mocked Context injected into the object under test...
    val mockContext = mock<Context> {
        on { getString(R.string.name_label) } doReturn FAKE_STRING
    }

    val myObjectUnderTest = ClassUnderTest(mockContext)

    // ...when the string is returned from the object under test...
    val result: String = myObjectUnderTest.getName()

    // ...then the result should be the expected one.
    assertEquals(result, FAKE_STRING)
  }
}

Mockito 프레임워크를 사용하는 방법을 자세히 알아보려면 Mockito API 참조샘플 코드SharedPreferencesHelperTest 클래스를 참고하세요. Android 테스트 Codelab도 사용해 보세요.

오류: "메서드의 ... 모의 개체가 생성되지 않았습니다."

모의 처리 가능한 Android 라이브러리는 Error: "Method ... not mocked 메시지로 메서드에 액세스하려고 하면 예외를 발생시킵니다.

발생한 예외가 테스트에 문제가 되는 경우 반환 유형에 따라 메서드가 대신 null 또는 0을 반환하도록 동작을 변경할 수 있습니다. 이렇게 하려면 프로젝트의 Groovy의 최상위 build.gradle 파일:

android {
  ...
  testOptions {
    unitTests.returnDefaultValues = true
  }