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']
}
}
...
}
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.
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 !
There are two ways:
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'
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: Now run your tests:
If you have build issues with product flavors then you should add publishNonDefault in build.gradle of your application:
android {
...
defaultConfig {
...
}
publishNonDefault true
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With