Viktor K
Viktor K

Reputation: 2173

Splitting unit and integration tests for android

Currently I have a test/src/java folder where all of the tests for the android application are stored (tests are done using junit, mockito and robolectric).

And I can run those using ./gradlew test

What I'd like to achieve is having two folders:

  1. integrationTest/src/java - for integration tests
  2. test/src/java - for unit tests

And also I'd like to run them separately, like ./gradlew test and ./gradlew integrationTest.

I've managed to split directories with tests using sourceSets like this:

    sourceSets {
        test {
            java {
                srcDirs = ['src/test/java', 'src/integrationTest/java', 'src/commonTest/java']
            }
            resources {
                srcDirs = ['src/test/resources', 'src/integrationTest/resources', 'src/commonTest/resources']
            }
        }
    }

And I had googled many examples on how to create custom test tasks, but most of them are related to java instead of android and the others are out-of-date. I've spent on that the whole day now and so if someone can help me I would really appreciate that.

Upvotes: 13

Views: 2098

Answers (3)

m-oliv
m-oliv

Reputation: 419

I had the same problem a few days ago.

In order to solve it and be able to run each type of test independently, I separated my tests like this:

// run only unit tests
test{
    include '**/unit/**'
    exclude '**/integration/**'
    doLast {
        println 'Unit tests execution finished.'
    }
}

// run only integration tests
task integrationTest(type: Test){
    include '**/integration/**'
    exclude '**/unit/**'
    doLast {
        println 'Integration tests execution finished.'
    }
}

// run all tests (unit + integration)
task allTests(type: Test){
    include '**/integration/**'
    include '**/unit/**'
    doLast {
        println 'All tests execution finished.'
    }
}

The include keyword indicates which files you want to include when executing the commands. If you want to run only your unit tests, you can only include the folder(s) that include your unit tests and exclude the folders that include your integration tests.

You can use a similar logic when creating a gradle command to run only your integration tests.

To execute your tests using this configuration and gradle, use:

  • ./gradlew test to execute the unit tests only.
  • ./gradlew integrationTests to execute the integration tests only.
  • ./gradlew allTeststo execute both the integration and the unit tests.

NOTE: You can setup the paths in the includes / excludes in order to include / exclude tests or classes when executing your tests. It is also possible to include only one test and exclude the others and vice-versa.

Upvotes: 2

fernandospr
fernandospr

Reputation: 3061

If your integration tests are instrumented tests, then you can just use the default folders test and androidTest and run them separately using ./gradlew test and ./gradlew connectedAndroidTest

Another way (if you can have the integration tests inside the test folder) would be to use separate packages inside the test folder and run the tests separately using:

./gradlew testDebug --tests="com.yourapplication.unittests.*"
./gradlew testDebug --tests="com.yourapplication.integrationtests.*"
...

Upvotes: 3

lance-java
lance-java

Reputation: 28101

Possibly something like

sourceSets {
    integrationTest {
        java {
            compileClasspath += main.output
            runtimeClasspath += main.output
            srcDir 'src/integrationTest/java'
        }
        resources.srcDir 'src/integrationTest/resources'
    }
}

configurations {
    integrationTestCompile { 
        extendsFrom compile 
    }
    integrationTestRuntime {
        extendsFrom runtime
    }
}

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

Then you could do

dependencies {
    integrationTestCompile 'org.seleniumhq.selenium:selenium-java:3.0.1'
    integrationTestRuntime 'com.foo:bar:1.0'
}

Upvotes: 0

Related Questions