고급 테스트 설정

Android 스튜디오에서 테스트명령줄에서 테스트에서는 기본적인 테스트 구성 설정과 실행 방법을 설명합니다. 그러나 앱 및 테스트의 요구사항이 더 복잡해지면 테스트 구성을 추가로 조정할 필요가 있을 수 있습니다. 다음의 작업은 그러한 고급 테스트 설정이 필요한 예입니다.

  • 특정 빌드 변형에만 적용되는 계측 테스트를 실행하거나 매니페스트 설정을 재정의합니다.
  • 테스트를 실행하는 빌드 유형을 변경하거나 Gradle 옵션을 구성합니다.
  • 계측 테스트를 자체 테스트 모듈로 추출합니다.
  • 지속적 통합 설정의 일부로 고급 테스트를 실행합니다.

이 페이지에서는 기본 설정이 요구사항에 맞지 않을 때 테스트를 구성하는 다양한 방법을 설명합니다.

빌드 변형의 계측 테스트 작성

프로젝트에 고유한 소스 세트를 갖는 빌드 변형이 포함되어 있는 경우 그러한 소스 세트에 상응하는 계측 테스트를 포함하는 것이 좋습니다. 이렇게 하면 테스트 코드를 체계적으로 유지하고 특정 빌드 변형에 적용되는 테스트만 실행할 수 있습니다.

계측 테스트를 빌드 변형에 연결하려면 src/androidTestVariantName에 있는 자체 소스 세트에 배치합니다.

src/androidTest/ 소스 세트에 포함된 계측 테스트는 모든 빌드 변형에서 공유됩니다. 앱의 'MyFlavor' 변형에 대한 테스트 APK를 빌드하는 경우 Gradle이 src/androidTest/src/androidTestMyFlavor/ 소스 세트를 결합합니다.

Android 스튜디오에서 빌드 변형의 테스트 소스 세트를 추가하려면 다음 단계를 따르세요.

  1. Project 창에서 메뉴를 클릭하고 Project 뷰를 선택합니다.
  2. 적합한 모듈 폴더 내에 있는 src 폴더를 마우스 오른쪽 버튼으로 클릭하고 New > Directory를 클릭합니다.
  3. 디렉터리 이름으로 'androidTestVariantName'을 입력합니다. 예를 들어 'MyFlavor'라는 빌드 변형이 있는 경우 디렉터리 이름 androidTestMyFlavor를 사용하세요.
  4. OK를 클릭합니다.
  5. 새 디렉터리를 마우스 오른쪽 버튼으로 클릭하고 New > Directory를 선택합니다.
  6. 디렉터리 이름으로 'java'를 입력한 후 OK를 클릭합니다.

이제 새 테스트 추가 단계에 따라 이 새로운 소스 세트에 테스트를 추가할 수 있습니다. Choose Destination Directory 대화상자에 도달하면 새 변형 테스트 소스 세트를 선택합니다.

다음 표는 앱의 코드 소스 세트에 상응하는 테스트 소스 세트 내에 계측 테스트 파일이 어떻게 배치되는지를 보여줍니다.

표 1. 앱 소스 코드 및 상응하는 계측 테스트 파일

앱 클래스 경로 일치하는 계측 테스트 클래스 경로
src/main/java/Example.java src/androidTest/java/AndroidExampleTest.java
src/myFlavor/java/Example.java src/androidTestMyFlavor/java/AndroidExampleTest.java

앱 소스 세트와 마찬가지로, Gradle 빌드는 다양한 테스트 소스 세트의 파일도 병합하고 재정의합니다. 이 경우 androidTestMyFlavor 소스 세트의 AndroidExampleTest.java 파일이 androidTest 소스 세트의 버전을 재정의합니다. 이는 제품 버전 소스 세트가 기본 소스 세트보다 우선순위가 높기 때문입니다.

빌드 변형 선택기에서 다른 버전을 선택하면 적합한 androidTest 폴더가 Android 뷰에 표시되어 사용되는 폴더를 보여줍니다.

MyFlavor 변형이 선택되고 androidTestMyFlavor 폴더가 Android 뷰에 표시됨
그림 1. MyFlavor 변형이 선택되고 androidTestMyFlavor 폴더가 Android 뷰에 표시됨

androidTestMyFlavor 폴더는 다른 변형이 선택되면 표시되지 않습니다.

OtherFlavor 변형이 선택되고 androidTestMyFlavor 폴더가 Android 뷰에 표시되지 않음
그림 2. OtherFlavor 변형이 선택되고 androidTestMyFlavor 폴더가 Android 뷰에 표시되지 않음

Project 뷰를 사용하면 약간 다르게 표시되지만 원칙은 동일하게 적용됩니다.

MyFlavor 변형이 선택되고 androidTestMyFlavor 폴더가 Project 뷰에서 활성 상태로 표시됨
그림 3. MyFlavor 변형이 선택되고 androidTestMyFlavor 폴더가 Project 뷰에서 활성 상태로 표시됨

다른 변형을 선택하면 androidTestMyFlavor 폴더가 계속 표시되지만 활성 상태로 표시되지는 않습니다.

OtherFlavor 변형이 선택되고 androidTestMyFlavor 폴더가 Project 뷰에서 활성 상태로 표시되지 않음
그림 4. OtherFlavor 변형이 선택되고 androidTestMyFlavor 폴더가 Project 뷰에서 활성 상태로 표시되지 않음

소스 세트가 병합되는 방식에 관한 자세한 내용은 소스 세트를 참고하세요.

계측 매니페스트 설정 구성

계측 테스트는 자체 AndroidManifest.xml 파일과 함께 별도의 APK에 빌드됩니다. Gradle은 테스트 APK를 빌드할 때 AndroidManifest.xml 파일을 자동으로 생성하고 <instrumentation> 노드로 이 파일을 구성합니다. Gradle이 자동으로 이 노드를 구성하는 이유 중 하나는 targetPackage 속성이 테스트 대상 앱의 패키지 이름을 올바르게 지정하도록 만들기 위해서입니다.

이 노드의 다른 설정을 변경하려면 테스트 소스 세트에서 또 다른 매니페스트 파일을 만들거나 다음 코드 샘플과 같이 모듈 수준 build.gradle 파일을 구성합니다. 전체 옵션 목록은 BaseFlavor API 참조에서 확인할 수 있습니다.

Groovy

android {
    ...
    defaultConfig {
        ...
        testApplicationId "com.example.test"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        testHandleProfiling true
        testFunctionalTest true
    }
}

Kotlin

android {
    ...
    defaultConfig {
        ...
        testApplicationId = "com.example.test"
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        testHandleProfiling = true
        testFunctionalTest = true
    }
}

Each product flavor you configure can override properties in the defaultConfig {} block. To learn more, go to Configure product flavors.

The properties in the snippet are:

Setting Description
testApplicationId Specifies the application ID for the test APK.
testInstrumentationRunner Specifies the fully qualified class name of the test instrumentation runner.
testHandleProfiling If set to true, enables the instrumentation class to start and stop profiling.
If set to false, profiling occurs the entire time the instrumentation class is running.
testFunctionalTest If set to true, indicates that the Android system should run the instrumentation class as a functional test.
The default value is false.

Change the test build type

By default, all instrumentation tests run against the debug build type. You can change this to another build type by using the testBuildType property in your module-level build.gradle file. For example, if you want to run your tests against your staging build type, edit the file as shown in the following snippet:

Groovy

android {
    ...
    testBuildType "staging"
}

Kotlin

android {
    ...
    testBuildType = "staging"
}

Gradle 테스트 옵션 구성

Android Gradle 플러그인을 사용하면 테스트 전체 또는 일부에 특정 옵션을 지정할 수 있습니다. 모듈 수준 build.gradle 파일에서 testOptions 블록을 사용하여 Gradle이 모든 테스트를 실행하는 방식을 변경하는 옵션을 지정하세요.

Groovy

android {
    ...
    // Encapsulates options for running tests.
    testOptions {
        reportDir "$rootDir/test-reports"
        resultsDir "$rootDir/test-results"
    }
}

Kotlin

android {
    ...
    // Encapsulates options for running tests.
    testOptions {
        reportDir "$rootDir/test-reports"
        resultsDir = "$rootDir/test-results"
    }
}

reportDir 속성은 Gradle이 테스트 보고서를 저장하는 디렉터리를 변경합니다. 기본적으로 Gradle은 path_to_your_project/module_name /build/outputs/reports/ 디렉터리에 테스트 보고서를 저장합니다. $rootDir은 현재 프로젝트의 루트 디렉터리를 기준으로 경로를 설정합니다.

resultsDir 속성은 Gradle이 테스트 결과를 저장하는 디렉터리를 변경합니다. 기본적으로 Gradle은 path_to_your_project/module_name /build/outputs/test-results/ 디렉터리에 테스트 결과를 저장합니다. $rootDir은 현재 프로젝트의 루트 디렉터리를 기준으로 경로를 설정합니다.

로컬 단위 테스트에만 옵션을 지정하려면 testOptions 내에서 unitTests 블록을 구성합니다.

Groovy

android {
    ...
    testOptions {
        ...
        // Encapsulates options for local unit tests.
        unitTests {
            returnDefaultValues true

            all {
                jvmArgs '-XX:MaxPermSize=256m'

                if (it.name == 'testDebugUnitTest') {
                    systemProperty 'debug', 'true'
                }
                ...
            }
        }
    }
}

Kotlin

android {
    ...
    testOptions {
        ...
        // Encapsulates options for local unit tests.
        unitTests {
            returnDefaultValues = true

            all {
                jvmArgs = listOf("-XX:MaxPermSize=256m")

                 if (it.name == "testDebugUnitTest") {
                    systemProperty = mapOf("debug" to "true")
                }
                ...
            }
        }
    }
}

기본적으로 로컬 단위 테스트에서는 테스트 중인 코드가 Android 플랫폼 API에 액세스를 시도할 때마다 예외가 발생합니다. 단, 직접 또는 Mockito와 같은 테스트 프레임워크를 사용하여 Android 종속 항목을 모의 처리하는 경우는 예외입니다. 그러나 플랫폼 API에 액세스할 때 테스트가 예외를 발생시키지 않고 null이나 0을 반환하도록 returnDefaultValues 속성을 사용 설정할 수 있습니다.

all 블록은 Gradle이 로컬 단위 테스트를 실행하는 방식을 제어하는 옵션을 캡슐화합니다. 지정할 수 있는 모든 옵션에 관한 목록은 Gradle 참조 문서를 확인하세요.

jvmArgs 속성은 테스트 JVM의 JVM 인수를 설정합니다.

작업 이름을 확인하여 지정한 테스트에만 옵션을 적용할 수도 있습니다. 스니펫 예에서 debug 속성은 true로 설정되어 있지만 testDebugUnitTest 작업에만 적용됩니다.

계측 테스트용으로 별도의 테스트 모듈 사용

계측 테스트 전용 모듈을 만들고 나머지 코드를 테스트에서 격리하려면 별도의 테스트 모듈을 만들고 라이브러리 모듈과 비슷하게 빌드를 구성합니다.

테스트 모듈을 만들려면 다음 단계를 진행하세요.

  1. 라이브러리 모듈을 만듭니다.
  2. 모듈 수준 build.gradle 파일에서 com.android.library 대신 com.android.test 플러그인을 적용합니다.
  3. Sync Project 를 클릭합니다.

테스트 모듈을 만든 후에 기본 소스 세트나 변형 소스 세트(예: src/main/java 또는 src/variant/java)에 테스트 코드를 포함할 수 있습니다. 앱 모듈에서 여러 제품 버전이 정의되는 경우 이러한 버전을 테스트 모듈에서 다시 만들 수 있습니다. 테스트 모듈은 변형 인식 종속 항목 관리를 사용하여 타겟 모듈에서 일치하는 버전을 테스트하려고 시도합니다.

기본적으로 테스트 모듈은 디버그 변형만 포함하고 테스트합니다. 하지만 테스트할 앱 프로젝트와 일치하는 새로운 빌드 유형을 만들 수도 있습니다. 테스트 모듈이 디버그 변형이 아닌 다른 빌드 유형을 테스트하게 하려면 다음과 같이 VariantFilter를 사용하여 테스트 프로젝트의 디버그 변형을 사용 중지하세요.

Groovy

android {
    variantFilter { variant ->
        if (variant.buildType.name.equals('debug')) {
            variant.setIgnore(true);
        }
    }
}

Kotlin

android {
    variantFilter {
        if (buildType.name == "debug") {
            ignore = true
        }
    }
}

테스트 모듈에서 앱의 특정 버전이나 빌드 유형만 타겟팅하려면 matchingFallbacks 속성을 사용하여 테스트하려는 변형만 타겟팅할 수 있습니다. 이렇게 하면 테스트 모듈에서 해당 변형을 직접 구성할 필요도 없습니다.