Android-Gradle-Robolectric 에서 TDD 하기

개발 이야기 2014. 6. 19. 12:16

얼마전 Android-Gradle-Robolectric 을 적용하는 블로그를 하나 썼습니다.
당시에는 Gradle-Robolectric 2.2 로 반영한것이었고 SingleTest 가 불가능한 상황이었습니다. 그래서 사실상 TDD 가 어려운 상황이었지요.


얼마 전 Gradle-Robolectric 이 2.2 -> 2.3 으로 올라오면서 Future Task 목록에 있던 Single Test 가 사라진 것으로 확인하고 부랴부랴 싱글 테스트가 되는지를 확인해보았고 잘 되는 것을 확인하였습니다.


그럼 이제 그에 대한 내용으로 적어보도록 하지요.

1. Gradle-Robolectric 설정하기


buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:0.11.+'
        classpath 'org.robolectric:robolectric-gradle-plugin:0.11.+'
    }
}

apply plugin: 'robolectric'

dependencies {
    repositories {
        mavenCentral()
    }

    androidTestCompile 'junit:junit:4.10'
    androidTestCompile 'org.robolectric:robolectric:2.3+'
    androidTestCompile 'com.squareup:fest-android:1.0.+'
}

robolectric {
    // configure the set of classes for JUnit tests
    include '**/*Test.class'
    exclude '**/espresso/**/*.class'

    // configure max heap size of the test JVM
    maxHeapSize = "2048m"
}

위와 같이 build.gradle 을 설정합니다.


2. [project명].iml 파일 설정하기

Test Class Path 설정



  
     
     
     

     

     
     
     
     
     
  


3. Android Test 용 폴더 및 패키지 구조

 

만약 Eclipse -> Android Studio 로 전환한 프로젝트라면....

android {
   sourceSet{
       main {
          //...중략...
       }
        
       androidTest.setRoot("test")

   }
}

위와 같이 설정하신 다음 $rootDir/test/ 에 위와 같은 구조를 따라주시면 됩니다.


4. Gradle-Robolectric 용 TestRunner 만들기
Android 의 모든 클래스들은 기본적으로 SDK 내에서 동작하도록 되어 있습니다. 그래서 Context 와 같은 특수한 객체가 없으면 동작하지 못하는 경우가 많습니다.

Robolectric 용 TestRunner 를 만들어서 동작하도록 해야합니다.

public class RobolectricGradleTestRunner extends RobolectricTestRunner {
    public RobolectricGradleTestRunner(Class testClass) throws InitializationError {
        super(testClass);
    }

    @Override
    protected AndroidManifest getAppManifest(Config config) {

        String manifestProperty = System.getProperty("android.manifest");

        if (config.manifest().equals(Config.DEFAULT) && manifestProperty != null) {
            String resProperty = System.getProperty("android.resources");
            String assetsProperty = System.getProperty("android.assets");
            return new AndroidManifest(Fs.fileFromPath(manifestProperty), Fs.fileFromPath(resProperty),
                    Fs.fileFromPath(assetsProperty));
        }
        return super.getAppManifest(config);

    }
}


위의 코드는 Robolectric 의 Gradle 용 코드에서 가져왔습니다 :)

위의 4가지 절차를 수행하시면 가장 기본적인 설정이 끝났습니다. 이제 테스트 코드를 작성해보겠습니다.


5. TestCode 작성하기

@Config(manifest = "src/main/AndroidManifest.xml", emulateSdk = 18)
@RunWith(RobolectricGradleTestRunner.class)
public class BeansInfoTest {

    @Test
    public void testCreateBeansInfo() throws Exception {
        BeanInfo beansInfo = new BeanInfo(null, "column", null, false);

        assertNotNull(beansInfo);

    }
}

위와 같이 테스트 코드를 작성 하시고 테스트를 돌리시면 아래와 같은 결과가 나옵니다.
(단! 테스트코드 Run 은 JUnit Tes 로 하셔야 합니다.)



언젠가부터 테스트 되지 않은 코드들은 마음 한 구석이 불안함이 컸습니다. 가끔은 저도 저를 못 믿을때가 많거든요 ^^

테스트 코드가 이러한 부분을 많이 커버해주었는데요. 이제 안드로이드도 테스트할 수 있는 코드를 만들 수 있어서 정말 기쁘네요.
(물론 이전부터 되었던 거지만 Android-Gradle 환경에서는 어려움이 많았지요)


위의 소스코드는 Github 에 정리되어 있습니다 :)

https://github.com/ZeroBrain/Android-Sqlite-Object-Convert


>>>>>> 2014.06.23 추가사항 <<<<<<

덧1
Eclipse -> Android Studio 로 이동한 프로젝트는 JUnit Test 가 잘 동작하지 않습니다.
아래와 같은 코드를 build.gradle 에 추가해주셔야 합니다.


tasks.whenTaskAdded {task ->
    if (task.name == 'testClasses') {
        task.dependsOn compileDebugTestJava
    }
}

robolectric 플러그인은 JUnit 테스트가 동작할 때 testClasses 라는 Task 를 동작시킵니다.
이 때 Test 클래스를 컴파일하도록 compileDebugTestJava Task 를 추가하도록 하였습니다.

덧2

2단계에서 설명한 내용 중 output-test 의 경로가 일정치 않습니다.
<output-test url="file://$MODULE_DIR$/build/test" />
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
위와 같이 주로 2가지의 경우가 있습니다. 가급적 실제 경로로 들어가셔서 클래스가 어느 위치에 있는지 확인해주세요.

덧3
Main Module, :LibModule 과 형식으로 프로젝트가 구성되어 있을 때에는
LibModule 에도 Robolectric 을 함께 정의해주십시요. 그렇지 않으면 Test 클래스가 컴파일되지 않더군요.

덧4
이제 조사한 자료를 실무에 적용하려니 이곳저곳에서 많이 이슈가 생기네요..
추가될 내용이 생기면 이 로그에 추가로 남기도록 하겠습니다.

덧5
Google - Android Studio 팀에서도 테스트 모듈에 대한 고민이 많나 봅니다.
가이드 문서 곳곳에 연결되지 않은 테스트 모듈 관련 로그들이 숨겨져있네요.

설정

트랙백

댓글