Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 841
Viktor K Avatar asked Dec 13 '16 09:12

Viktor K


People also ask

What are integration tests Android?

Integration tests verify the way different parts of your app work together. They are slower than unit tests, and should therefore only be used when you need to test how things interact. When interacting with the Android framework you can rely on an Android device or emulator, or use Robolectric.

Should you separate unit and integration tests?

Keep your testing suites separateIntegration tests should not be run together with unit tests. Developers working on specific business logic in the code must be able to run unit tests and get near-immediate feedback to ensure that they haven't broken anything before committing code.

What is the difference between integration test and unit test?

Unit Testing is a kind of white box testing, whereas Integration Testing is a kind of black-box testing. For Unit Testing, accessibility of code is required, as it tests the written code, while for Integration Testing, access to code is not required, since it tests the interactions and interfaces between modules.

Can JUnit be used for Integration testing?

And what are they using it for? Even after 20 years of JUnit's existence it is still mostly being used for unit tests. If you are lucky you may see an integration test or two. JUnit is, in fact, much more than a unit testing framework.


2 Answers

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.*"
...
like image 131
fernandospr Avatar answered Nov 07 '22 06:11

fernandospr


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.

like image 23
m-oliv Avatar answered Nov 07 '22 07:11

m-oliv