The Android Developer Challenge is back! Submit your idea before December 2.

앱 테스트하기

Android 스튜디오는 테스트 작업을 간단하게 수행할 수 있도록 설계되었습니다. 몇 번의 클릭만으로 로컬 JVM에서 실행되는 JUnit 테스트나 기기에서 실행되는 계측 테스트를 설정할 수 있습니다. 물론, 로컬 단위 테스트에서 Android API 호출을 테스트하는 Mockito 및 계측 테스트에서 사용자 상호작용을 시험하는 Espresso 또는 UI Automator를 통합하여 테스트 기능을 확장할 수도 있습니다. Espresso Test Recorder를 사용하여 Espresso 테스트를 자동으로 생성할 수 있습니다.

이 페이지에서는 Android 스튜디오에서 새 테스트를 앱에 추가하고 이를 실행하는 방법을 설명하는 기본적인 정보를 제공합니다.

테스트 작성과 관련한 전체 안내 가이드는 Android에서 앱 테스트하기를 참고하세요.

테스트 유형 및 위치

테스트 코드의 위치는 작성하는 테스트의 유형에 따라 결정됩니다. Android 스튜디오에서는 다음과 같은 두 가지 테스트 유형을 지원하는 소스 코드 디렉터리(소스 세트)를 제공합니다.

로컬 단위 테스트

위치: module-name/src/test/java/

컴퓨터의 로컬 JVM(Java Virtual Machine)에서 실행되는 테스트입니다. 테스트에 Android 프레임워크 종속성이 없거나 Android 프레임워크 종속성을 모의 구현할 수 있는 경우 이 테스트를 사용하면 실행 시간을 최소화할 수 있습니다.

런타임에 모든 final 수정자가 삭제된 수정 버전의 android.jar에 이러한 테스트가 실행됩니다. 여기서는 Mockito와 같이 흔히 사용되는 모의 라이브러리를 사용할 수 있습니다.

계측 테스트

위치: module-name/src/androidTest/java/

하드웨어 기기나 에뮬레이터에서 실행되는 테스트입니다. 이 테스트는 Instrumentation API에 액세스할 수 있으며 테스트하는 앱의 정보(예: Context)에 액세스할 권한을 개발자에게 제공합니다. 이 테스트에서 개발자는 테스트 대상 앱을 테스트 코드에서 제어할 수 있습니다. 사용자 상호작용을 자동화하는 통합 및 기능적 UI 테스트를 작성하거나 테스트에 모의 객체가 충족할 수 없는 Android 종속성이 있는 경우 이 테스트를 사용합니다.

계측 테스트는 앱 APK와는 별개인 APK로 빌드되므로 자체 AndroidManifest.xml 파일이 있어야 합니다. 하지만 Gradle이 빌드 과정에서 이 파일을 자동으로 생성하므로, 파일은 프로젝트 소스 세트에는 표시되지 않습니다. 필요한 경우 자체 manifest 파일을 추가하여 'minSdkVersion'에 다른 값을 지정하거나 테스트 전용 실행 리스너를 등록할 수 있습니다. 앱을 빌드하면 Gradle이 여러 manifest 파일을 단일 manifest로 병합합니다.

Gradle 빌드는 프로젝트의 앱 소스 세트에 수행하는 것과 동일한 방식으로 이러한 테스트 소스 세트를 해석합니다. 따라서 개발자는 빌드 변형을 기반으로 테스트를 작성할 수 있습니다.

새 프로젝트를 만들거나 앱 모듈을 추가하면 Android 스튜디오가 위에 나열되어 있는 테스트 소스 세트를 생성하고 각 테스트 소스 세트에 예제 테스트 파일을 포함합니다. 그림 1에 나온 것처럼 Project 창에서 이 항목을 확인할 수 있습니다.

그림 1. 프로젝트의 (1) 계측 테스트 및 (2) 로컬 JVM 테스트가 Project 뷰(왼쪽)나 Android 뷰(오른쪽)에 표시됩니다.

새 테스트 추가하기

로컬 단위 테스트 또는 계측 테스트를 작성하려면 다음 단계에 따라 특정 클래스 또는 메서드의 새 테스트를 작성하면 됩니다.

  1. 테스트할 코드가 포함된 자바 파일을 엽니다.
  2. 테스트하려는 클래스 또는 메서드를 클릭한 후 Ctrl+Shift+T(⇧⌘T)를 누릅니다.
  3. 나타나는 메뉴에서 Create New Test를 클릭합니다.
  4. Create Test 대화상자에서 필드를 수정하고 생성할 메서드를 선택한 후 OK를 클릭합니다.
  5. Choose Destination Directory 대화상자에서 작성하려는 테스트의 유형에 해당하는 소스 세트를 클릭합니다. 계측 테스트의 경우 androidTest를 선택하고 로컬 단위 테스트의 경우 test를 선택한 후 OK를 클릭합니다.

또는, 다음과 같이 적합한 테스트 소스 세트에서 일반 자바 파일을 생성할 수도 있습니다.

  1. 왼쪽의 Project 창에서 드롭다운 메뉴를 클릭하고 Project 뷰를 선택합니다.
  2. 적합한 모듈 폴더와 여기에 중첩된 src 폴더를 확장합니다. 로컬 단위 테스트를 추가하려면 test 폴더와 여기에 중첩된 java 폴더를 확장하고, 계측 테스트를 추가하려면 androidTest 폴더와 여기에 중첩된 java 폴더를 확장합니다.
  3. 자바 패키지 디렉터리를 마우스 오른쪽 버튼으로 클릭하고 New > Java Class를 선택합니다.
  4. 파일의 이름을 지정한 후 OK를 클릭합니다.

또한, 앱 모듈의 build.gradle 파일에 테스트 라이브러리 종속성도 지정해야 합니다.

dependencies {
        // Required for local unit tests (JUnit 4 framework)
        testImplementation 'junit:junit:4.12'

        // Required for instrumented tests
        androidTestImplementation 'com.android.support:support-annotations:24.0.0'
        androidTestImplementation 'com.android.support.test:runner:0.5'
    }
    

기타 선택적 라이브러리 종속성 및 테스트 작성 방법을 자세히 알아보려면 로컬 단위 테스트 빌드하기계측 단위 테스트 빌드하기를 참고하세요.

앱 APK와 테스트 APK 사이의 충돌 해결하기

앱 APK와 테스트 APK는 동일한 classpaths를 공유합니다. 따라서, 두 APK가 동일 라이브러리의 서로 다른 버전에 종속되는 경우 빌드 오류가 발생할 수 있습니다. Gradle에서 이러한 버전 충돌을 감지할 수 없는 경우 앱이 정상적으로 작동하지 않거나 런타임 도중에 다운될 수 있습니다.

자세한 내용은 종속성 해결 오류 수정을 참조하세요.

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

프로젝트에 고유한 소스 세트를 갖는 빌드 변형이 포함되어 있는 경우 상응하는 계측 테스트 소스 세트가 필요할 수 있습니다. 빌드 변형에 해당하는 소스 세트에 계측 테스트를 작성하면 테스트 코드를 체계적으로 유지하고 특정 빌드 변형에 적용되는 테스트만 실행할 수 있습니다.

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

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

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

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

예를 들어, 다음 표에서는 계측 테스트 파일이 저장되는 소스 세트가 앱의 코드 소스 세트에 어떤 식으로 대응되는지를 보여줍니다.

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

앱 소스 세트와 마찬가지로, Gradle 빌드는 다양한 테스트 소스 세트의 파일도 병합하고 재정의합니다. 이 경우 'androidTestMyFlavor' 소스 세트의 AndroidFooTest.java 파일이 'androidTest' 소스 세트의 버전을 재정의합니다. 소스 세트가 병합되는 방식을 자세히 알아보려면 빌드 구성을 참고하세요.

앱 소스 세트 및 테스트 소스 세트에 빌드 변형을 사용해야 하는 또 다른 이유는 모의 종속성을 통해 밀폐 테스트를 작성하기 위해서입니다. 즉, 종속성 모조 구현(예: 네트워크 요청 또는 일반적으로 취약한 기기 센서 데이터)이 포함된 앱의 제품 버전을 만든 후 상응하는 모의 테스트 소스 세트를 추가할 수 있습니다. 자세한 내용은 밀폐 테스트에 제품 버전을 활용하는 방법을 설명하는 블로그 게시물을 참고하세요.

계측 manifest 설정 구성

Gradle은 테스트 APK를 빌드할 때 AndroidManifest.xml 파일을 자동으로 생성하고 <instrumentation> 노드로 이 파일을 구성합니다. Gradle이 자동으로 이 노드를 구성하는 이유 중 하나는 targetPackage 속성이 테스트 중인 앱의 패키지 이름을 올바르게 지정하도록 만들기 위해서입니다. 이 노드의 일부 설정을 변경하려면 또 다른 manifest 파일을 테스트 소스 세트에 만들거나 모듈 레벨 build.gradle 파일을 구성하면 됩니다(다음 코드 샘플 참조).

    android {
      ...
      // Each product flavor you configure can override properties in the
      // defaultConfig {} block. To learn more, go to Configure product flavors.
      defaultConfig {
        ...
        // Specifies the application ID for the test APK.
        testApplicationId "com.test.foo"
        // Specifies the fully-qualified class name of the test instrumentation runner.
        testInstrumentationRunner "android.test.InstrumentationTestRunner"
        // If set to 'true', enables the instrumentation class to start and stop profiling.
        // If set to false (default), profiling occurs the entire time the instrumentation
        // class is running.
        testHandleProfiling true
        // If set to 'true', indicates that the Android system should run the instrumentation
        // class as a functional test. The default value is 'false'
        testFunctionalTest true
      }
    }
    ...
    

테스트 빌드 유형 변경

기본적으로 모든 테스트는 특정 디버그 빌드 유형에 관해 실행됩니다. 모듈 레벨 build.gradle 파일의 testBuildType 속성을 사용하여 이 빌드 유형을 다른 빌드 유형으로 변경할 수 있습니다. 예를 들어 'staging' 빌드 유형에 관해 테스트를 실행하려면 다음 스니펫에 나온 대로 파일을 수정합니다.

android {
        ...
        testBuildType "staging"
    }
    

Gradle 테스트 옵션 구성

Gradle용 Android 플러그인을 사용하면 단위 테스트 모두 또는 일부 단위 테스트에만 특정 옵션을 지정할 수 있습니다. 모듈 레벨 build.gradle 파일에서 testOptions {} 블록을 사용하여 Gradle에서 모든 테스트가 실행되는 방식을 변경하는 옵션을 지정합니다.

    android {
      ...
      // Encapsulates options for running tests.
      testOptions {
        // Changes the directory where Gradle saves test reports. By default, Gradle saves test reports
        // in the path_to_your_project/module_name/build/outputs/reports/ directory.
        // '$rootDir' sets the path relative to the root directory of the current project.
        reportDir "$rootDir/test-reports"
        // Changes the directory where Gradle saves test results. By default, Gradle saves test results
        // in the path_to_your_project/module_name/build/outputs/test-results/ directory.
        // '$rootDir' sets the path relative to the root directory of the current project.
        resultsDir "$rootDir/test-results"
      }
    }
    

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

    android {
      ...
      testOptions {
        ...
        // Encapsulates options for local unit tests.
        unitTests {
          // By default, local unit tests throw an exception any time the code you are testing tries to access
          // Android platform APIs (unless you mock Android dependencies yourself or with a testing
          // framework like Mockito). However, you can enable the following property so that the test
          // returns either null or zero when accessing platform APIs, rather than throwing an exception.
          returnDefaultValues true

          // Encapsulates options for controlling how Gradle executes local unit tests. For a list
          // of all the options you can specify, read Gradle's reference documentation.
          all {
            // Sets JVM argument(s) for the test JVM(s).
            jvmArgs '-XX:MaxPermSize=256m'

            // You can also check the task name to apply options to only the tests you specify.
            if (it.name == 'testDebugUnitTest') {
              systemProperty 'debug', 'true'
            }
            ...
          }
        }
      }
    }
    

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

한 모듈을 계측 테스트 전용으로 사용하고 코드의 나머지 부분을 테스트에서 격리하려는 경우 별도의 테스트 모듈을 만들어 이 모듈의 빌드를 라이브러리 모듈과 비슷하게 구성하면 됩니다. 테스트 모듈을 만들려면 다음 단계를 진행하세요.

  1. 라이브러리 모듈을 만듭니다.
  2. 모듈 레벨 빌드 파일에서 com.android.library 대신 com.android.test 플러그인을 적용합니다.
  3. 프로젝트를 동기화합니다.

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

기본적으로 테스트 모듈은 debug 변형만 포함하고 테스트합니다. 하지만 테스트되는 앱 프로젝트와 일치하는 새로운 빌드 유형을 만들 수 있습니다. 테스트 모듈이 디버그 빌드가 아닌 다른 빌드 유형을 테스트하게 하려면 VariantFilter를 사용하여 debug 변형을 테스트 프로젝트에서 사용 중지합니다(아래 참조).

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

앱의 특정 버전이나 빌드 유형만 대상으로 하는 테스트 모듈을 만들려면 matchingFallbacks 속성을 사용하여 테스트하려는 변형만 대상으로 지정하면 됩니다. 이렇게 하면 테스트 모듈이 대상 변형을 직접 구성할 필요가 없습니다.

테스트 실행하기

테스트를 실행하려면 다음 단계를 진행하세요.

  1. 툴바에서 Sync Project 를 클릭하여 프로젝트가 Gradle과 동기화되도록 합니다.
  2. 다음 방법 중 하나로 테스트를 실행합니다.
    • Project 창에서 테스트를 마우스 오른쪽 버튼으로 클릭하고 Run 을 클릭합니다.
    • 코드 편집기에서 테스트 파일의 클래스 또는 메서드를 마우스 오른쪽 버튼으로 클릭하고 Run 을 클릭하여 클래스의 모든 메서드를 테스트합니다.
    • 모든 테스트를 실행하려면 테스트 디렉터리를 마우스 오른쪽 버튼으로 클릭하고 Run tests 를 클릭합니다.

테스트는 기본적으로 Android 스튜디오의 기본 실행 구성을 사용하여 실행됩니다. 계측 실행기 및 배포 옵션과 같은 일부 실행 설정을 변경하려는 경우 Run/Debug Configurations 대화상자(Run > Edit Configurations 클릭)에서 실행 구성을 수정하면 됩니다.

테스트 범위 보기

로컬 단위 테스트에 테스트 범위 도구를 사용하여 단위 테스트에서 다루는 앱 코드의 비율과 영역을 추적할 수 있습니다. 테스트 범위 도구를 사용하여 앱을 구성하는 요소, 클래스, 메서드, 코드 줄이 적절하게 테스트되었는지 확인하세요.

단위 테스트를 실행하는 데는 여러 방법이 있으며 IntelliJ의 Running with Coverage(범위를 사용하여 실행) 페이지에서 이 방법을 설명합니다. 다음 절차는 편집기에서 인라인으로 단위 테스트를 실행하는 방법을 보여줍니다.

  1. 실행하려는 단위 테스트를 더블클릭합니다.
  2. 편집기에서 범위가 포함된 실행하려는 줄에 커서를 배치합니다.
    • 클래스 선언에 커서를 배치하면 클래스의 모든 테스트 메서드가 실행됩니다.
    • 메서드 선언에 커서를 배치하면 메서드의 모든 코드가 실행됩니다.
    • 메서드 내의 특정 줄에 커서를 배치하면 이 줄만 실행됩니다.
  3. 커서를 배치한 줄을 마우스 오른쪽 버튼으로 클릭합니다.
  4. 컨텍스트 메뉴에서 Run 테스트 이름 with coverage를 선택합니다.

    범위 도구 창이 표시됩니다.

그림 2는 덧셈, 뺄셈, 곱셈, 나눗셈을 테스트하는 계산기 단위 테스트의 범위 도구 창입니다.

그림 2. 애플리케이션의 코드 범위 비율을 확인합니다.

로컬 단위 테스트를 자세히 알아보려면 로컬 단위 테스트 빌드하기를 참고하세요.

테스트 결과 보기

JUnit 테스트나 계측 테스트를 실행하는 경우 Run 창에 결과가 표시됩니다. 녹색 막대는 모든 테스트가 성공했음을 의미하고, 빨간 막대는 테스트 한 개 이상이 실패했음을 의미합니다. 그림 3은 성공적인 테스트 실행을 보여줍니다.

그림 3. 테스트 결과가 Run 창에 표시됩니다.

Run 창의 왼쪽에는 테스트가 트리 보기로 표시되고 오른쪽에 있는 출력 창에는 현재 테스트 모음과 관련한 결과 및 메시지가 표시됩니다. 툴바, 컨텍스트 메뉴, 상태 아이콘을 다음과 같이 사용하여 테스트 결과를 관리합니다.

  1. 실행 툴바를 사용하여 현재 테스트를 재실행하고, 현재 테스트를 중지하고, 실패한 테스트를 재실행(단위 테스트에서만 사용 가능하므로 표시되지 않음)하고, 출력을 일시중지하고, 스레드를 덤프할 수 있습니다.
  2. 테스트 툴바를 사용하여 테스트 결과를 필터링하고 정렬할 수 있습니다. 또한, 노드를 확장하거나 축소하고, 테스트 범위를 표시하고, 테스트 결과를 가져오거나 내보낼 수도 있습니다.
  3. 컨텍스트 메뉴 를 클릭하면 실행 중인 테스트를 추적하고, 인라인 통계를 표시하고, 스택 추적으로 스크롤하고, 예외 위치에서 소스 코드를 열고, 소스로 자동 스크롤하고, 테스트 실행 완료 시 첫 번째 실패한 테스트를 선택할 수 있습니다.
  4. 테스트 상태 아이콘은 테스트에 오류가 있는지 여부 및 무시, 실패, 진행 중, 통과, 일시중지, 종료, 실행 안함과 같은 테스트 상태를 나타냅니다.
  5. 트리 보기에서 줄을 마우스 오른쪽 버튼으로 클릭하면 표시되는 컨텍스트 메뉴를 사용하여 디버그 모드로 테스트를 실행하거나, 테스트 소스 코드 파일을 열거나, 테스트 중인 소스 코드에서 특정 줄로 건너뛸 수 있습니다.

Run 창, 창의 툴바 및 컨텍스트 메뉴를 자세히 알아보려면 IntelliJ의 Test Runner Tab(테스트 실행기 탭) 페이지를 참고하세요.

인라인 통계 보기

테스트 실행에 걸린 시간을 알아보려면 다음을 따르세요.

  1. 톱니바퀴 아이콘 을 클릭합니다.
  2. 드롭다운 목록에서 Show Inline Statistics를 선택합니다.

    경과된 시간(밀리초 단위)이 테스트 오른쪽에 표시됩니다.

문자열 비교하기

단위 테스트에 두 문자열 객체를 비교한 결과 assertEquals() 실패가 포함되어 있는 경우 다음과 같은 방법으로 두 문자열 객체 사이의 차이를 확인하여 실패의 원인을 알아낼 수 있습니다.

  1. 출력 창에서 Click to see difference 링크를 클릭합니다.
  2. IntelliJ Differences viewer for files(파일의 차이 뷰어) 페이지의 설명대로 Differences viewer에서 차이를 탐색합니다.

테스트 결과 내보내기

다음과 같은 방법으로 테스트 결과를 XML 또는 HTML 형식으로 내보낼 수 있습니다.

  1. Export Test Results 를 클릭합니다.
  2. Export Test Results 대화상자에게 형식 및 출력 정보를 입력한 후 OK를 클릭합니다.

    내보낸 테스트 결과가 지정 폴더에 저장됩니다.

테스트 결과 가져오기

내보낸 테스트 결과를 다음과 같은 방법으로 가져올 수 있습니다.

  1. Import Test Results 를 클릭합니다.
  2. 드롭다운 메뉴에서 가져오려는 파일을 선택합니다.

    가져온 테스트 결과가 Run 창에 표시됩니다.