안드로이드 Gradle Test

Android application Test 방법

크게 2가지가 있습니다. 안드로이트 테스트(Instrumentation Test)와 Local PC의 JVM을 활용하는 새로운 개념의 Local Unit Test 입니다. 

참고) 로컬 유닛 테스트는 로컬 JVM을 활용하기 때문에 타깃 디바이스와 연결피 필요없습니다. 그리고 테스트 코드의 전체 실행속도가 향상되는 효과가 있습니다. 안드로이드 테스트에서는 APK를 생성하여 타깃 디바이스에 설치하고 실행하는 과정에서 시간 소모가 많은 편입니다.
Gradle을 활용화여 안드로이드 테스트 코드와 로컬 유닛테스트코드를 실행하는 방법을 알아보겠습니다.

로컬 유닛 테스트

app module의 build.gradle을 보시겠습니다. dpendencies부분에 아래와 같이 testCompile이 웬만하면 디폴트로 지정되어있으실겁니다.

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
}

그리고 ExampleUnitTest 클래스를 보시면 아래와 같이 코드가 미리작성되어있는것을 확인하실 수 있습니다. Junit4에서는 테스트코드에 @Test라는 애너테이션을 부착합니다.

public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        assertEquals(4, 2 + 2);
    }
}

해당 unitTest 클래스 오른쪽 마우스로누르고, run “ExampleUnitTest” 선택시 정상적으로 테스트됩니다.
로컬유닛테스트를 실행할때 호출되는 중요한 Gradle Task는 다음과 같습니다.

:app:mockableAndroidJar UP-TO-DATE
:app:compileDebugUnitTestSources UP-TO-DATE

1. mock(app:mockableAndroidJar ) 테스크는 안드로이드의 android.jar 파일을 mock 인터페이스로 컴파일합니다. 로컬 유닛 테스트가 동작하려면 안드로이드 코드에 대한 mock 인터페이스가 필요합니다. mock 인터페이스 호출 시, 가짜객체를 주입하는 경우도 있습니다. 가짜 객체(mock object)를 이용한 테스트 기법은 구글문서를 참고하십시오.
mock 테스트 실행결과는 /build/generated/mockable-android-26.jar(26은 버전명) 입니다. 
2. complieDebugUnitTestSources 태스크입니다. 태스크 이름자체대로 디버그 모드로 로컬 유닛 테스트 코드를 컴파일합니다. 릴리즈 모드일때는 릴리즈 이름에 맞게 테스크가 실행되는것을 확인하실 수 있습니다. 
또한, 콘솔에서도 테스트코드를 실행하실 수 있습니다. HTML로 결과가 출력되는데요.  프로젝트 폴더에서 cmd창을 연 후,
> gradlew :app:testDebug 
와같이 치신후 엔터를 누르고, app/build/reports/tests/debug 폴더에 테스트 결과를 확인하실 수 있습니다.

안드로이드 테스트

안드로이드 테스트코드는 Activity, Fragment, ButtonView, TextView 등 UI컴포넌트와, 유틸리티클래스와 같은 Java클래스 모두 테스트할 수 있습니다. 다만 에뮬레이터나, 타깃 디바이스에서 실행해야하는 제약이 있습니다 .
저는 MainActivityTest라는 클래스를 만들고 아래와 같이 코드작성 후, 실시해보겠습니다.

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
    public MainActivityTest() {
        super(MainActivity.class);
    }


    public  void testHelloLabel(){
        Activity ac = getActivity();
}

app 모듈의경우 /app/src/androidTest/java 폴더에 위치하고있습니다. 실행하는 방법은 로컬 유닛테스트와 유사합니다.
오른쪽마우스 누르고, run “MainActivityTest” 를 실행합니다.
:app:compileDebugAndroidTestSources
이번에 실행된 gradle test는 unitTest가 아닌, AndroidTest로 바뀐것을 확인하실 수 있습니다.
콘솔에서도 역시 확인하실 수 있습니다.
gradlew :app:connectedAndroidTest + 엔터 치시면됩니다.gradle 콘솔창에 뜨듯이 진행후, 완료구문을 확인하실 수 있습니다.

Espresso 연동하기

Espresso는 Android Testing Support Library에 편입되었습니다. 강력한 테스팅 도구이죠. 연동하는 방법을 살펴보시겠습니다.
app모듈의 build.gradle의 내용 추가입니다.

defaultconfig{
  testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

그다음 denependencies블록에 추가할 내용입니다.

androidTestCompile 'com.android.support.test:runner:0.4.1'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
compile 'com.android.support:appcompat-v7:23.0.1'

로컬 유닛 테스트의 제약사항

로컬 유닛테스트 같은 경우 andoir.util.Log 클래스에 대한, mock 인터페이스가 제공되지안항 오류를 낼때가있습니다.
이를 피하려면  모듈 build.gradle에 다음 내용을 추가해야합니다.

android{
  testOptions{
    unitTests.returnDefaultValues = true   
  }
}

근본적으로 해결하려면 PowerMock과 같은 라이브러리를 활용하여 log 클래스의 static 메서드를 위한 가짜 객체를 주입하는 방법이 있습니다. PowerMock 관련 문서를 참조하시기 바랍니다.

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다