Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to place Android (instrumentation) test files outside of project directory?

I have an Android project (generated by Cordova) that I want to add (instrumentation) tests to. It has only one MainActivity.java that should be tested.

Normally this means adding some dependencies to build.gradle and creating a file /src/androidTest/java/org/example/package/MainActivityTest.java with an MainActivityTest class and some test methods. (In Android Studio I can even generate those by using Run -> "Record Espresso Test" - so really simple and works).

Unfortunately, I now have the requirement that those test files do actually live outside the project directory. There should be only minimal changes on the existing Cordova project (as it is regenerated and handled as a build artifact). The MainActivity.java would best be in the same root folder where the Android project is in /android.

How can I achieve that?


The build.gradle changes can be added to a build-extras.gradle file that the real build.gradle already includes, so this is taken care of.

But I have no idea how to place the MainActivityTest.java outside of the project folder structure and still be able run it inside the project.

For iOS you can link external files into the project with absolute paths. Something like that would be perfect here as well.

I looked at sourceSets but I am not sure how to integrate this in the Cordova Android project which already has this non default (I think?) sourceSets:

android {
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
            jniLibs.srcDirs = ['libs']
        }
    }
    ...
}     
like image 747
janpio Avatar asked Aug 11 '17 09:08

janpio


People also ask

Which folder of an Android Studio project contains instrumental tests?

In your Android Studio project, you store the source files for instrumented tests in module-name/src/androidTest/java/ . This directory already exists when you create a new project and contains an example instrumented test.

Can I delete the test folder in Android Studio?

Yes You can delete them ,you can go to build. gradle and then remove following dependencies which comes preloaded in any new android project. and then click on the androidTest and Test package and Press Delete they will be removed !


1 Answers

There are two ways:

  1. You can create independent Android project (which you can put at any folder outside the app project) for your instrumentation tests only using Android Studio 3.0. For this purpose I used:

    Android Studio 3.0 Beta 6

    Android Gradle Plugin: 'com.android.tools.build:gradle:3.0.0-beta6'

  2. You can create a separate module (which you can put at any folder outside the app project) for your instrumentation tests. For this you can use:

    With Android Studio 3.0.0

    With Android Gradle Plugin 3.0.0

    With Gradle Wrapper 4.2.1-all

    If you receive an error that the AndroidManifest of the instrumentation-test-module and the app-module cannot be merged, you might be limited to old Gradle versions which

    Tested with Android Studio 2.3.3 and 3.0.0

    The highest Android Gradle Plugin will be 2.2.3

    Gradle Wrapper 3.3-all (or 3.4.1 / 4.2.1)

    Note: This is broken for Android Gradle Plugin 2.3.0!

I created SAMPLE PROJECT to demonstrate structure of tests in both cases.


The build.gradle of the project/module has to use this plugin:

// A plugin used for test-only-modules
apply plugin: 'com.android.test'

This plugin uses TestExtension (link to its DSL). With TestExtension and 'com.android.test' plugin your gradle file will look like:

apply plugin: 'com.android.test'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.2"
    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 26

        // The package name of the test app
        testApplicationId 'com.example.android.testing.espresso.BasicSample.tests'
        // The Instrumentation test runner used to run tests.
        testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
    }
    // Set the target app project. The module specified here should contain the production code
    // test should run against.
    targetProjectPath ':app'
}

dependencies {
    // Testing-only dependencies
    // Force usage of support annotations in the test app, since it is internally used by the runner module.
    compile 'junit:junit:4.12'
    compile 'com.android.support:support-annotations:25.4.0'
    compile 'com.android.support.test:runner:1.0.1'
    compile 'com.android.support.test:rules:1.0.1'
    compile 'com.android.support.test.espresso:espresso-core:3.0.1'
}

Pay attention that here no "androidTestCompile" is supported!

Do not forget to create AndroidManifest.xml. It will look like:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.android.testing.espresso.BasicSample.tests">

<!-- Specify runner and target application package -->
<instrumentation
    android:name="android.support.test.runner.AndroidJUnitRunner"
    android:functionalTest="false"
    android:handleProfiling="false"
    android:label="Tests for com.example.android.testing.espresso.BasicSample"
    android:targetPackage="com.example.android.testing.espresso.BasicSample"/>

    <application>
        <uses-library android:name="android.test.runner" />
    </application>

</manifest>

Pay attention that test source files are in "main" folder (not androidTest):

src->main->java->package.name.folders

Then you can link this test project to your application project in settings.gradle:

include ':module-androidTest'
project(':module-androidTest').projectDir = new File("../BasicSampleTests/test")

In Android Studio you must create "Android Instrumented Tests" run configuration. It will look like: enter image description here Now run your tests:

enter image description here

If you have build issues with product flavors then you should add publishNonDefault in build.gradle of your application:

android {
    ...
    defaultConfig {
       ...
    }
    publishNonDefault true
}
like image 189
Sheikh Avatar answered Oct 01 '22 02:10

Sheikh