Home » Android » Separating integration tests from unit tests in Android Studio

Separating integration tests from unit tests in Android Studio

Posted by: admin May 14, 2020 Leave a comment

Questions:

I’m trying to separate out integration tests in Android Studio 0.9.

I have added the following to the build file:

sourceSets {
    integrationTest {
        java.srcDir file('src/integrationTest/java')
    }
}

task integrationTest(type: Test) {
    testClassesDir = sourceSets.integrationTest.output.classesDir
    classpath = sourceSets.integrationTest.runtimeClasspath
}

I’ve run into a couple of issues:

  1. The task will run but it doesn’t have the rest of the project files available so I get errors about missing classes. There are some Java specific solutions I’ve found such as:

    But I haven’t been able to figure out how to get this to work with Android Studio. Various combinations of main and main.output and playing around with dependencies don’t seem to work, I get errors like:

    Error:(33, 0) Could not find property 'main' on SourceSet container..
    

    Which makes sense as the android plugin defines its own source sets, but these don’t work either.

  2. The IDE doesn’t recognise the directory as a test source directory. For testing purposes I changed the source set name to androidTest and it correctly gets the green folder icon and the tests are run along with the existing unit tests that are already defined in androidTest.

How to&Answers:

@sm4’s answer works indeed for a Java module (with apply plugin: 'java'), but unfortunately not for Android application (apply plugin: 'com.android.application') nor Android library modules (apply plugin: com.android.library).

But I have found a workaround:
Create the folders for your integration tests:

src/integrationTest/java
src/integrationTest/res

Add the sourceSets for your new folders:

sourceSets {
    integrationTest {
        java {
            srcDir file('src/integrationTest/java')
        }
        res {
            srcDir file('src/integrationTest/res')
        }
    }
}

In a pure Java module the java folder would now turn green and the res folder icon would change. In an Android application/library module it does not.

Now create a product flavor identically named as the folder configured in the sourceSet, and it works!

productFlavors {
    integrationTest {
    }
}

And to put a cherry on top:

configurations {
    integrationTestCompile.extendsFrom testCompile
}

Answer:

I’ve done exactly this kind of separation in Gradle, but for a pure Java project, not Android. You are not specifying the classpath in source sets, which I think is the issue. Here’s the relevant part of the build.gradle:

sourceSets {
    integration {
        java {
            compileClasspath += main.output + test.output
            runtimeClasspath += main.output + test.output
            srcDir file('src/integration/java')
        }
        resources {
            srcDir 'src/integration/resources'
        }
    }
}

configurations {
    integrationCompile.extendsFrom testCompile
    integrationRuntime.extendsFrom testRuntime
}

task integrationTest(group: "verification", type: Test) {
    testClassesDir = sourceSets.integration.output.classesDir
    classpath = sourceSets.integration.runtimeClasspath
}
integrationTest.dependsOn testClasses

IntelliJ idea picks up the folders under src/integration if they have the standard names (java, resources).