Set different minSdkVersion for testAndroid than for main app
AndroidTestingAndroid UiautomatorAndroid Problem Overview
Is it possible to set a different minSdkVersion
for tests than for the app itself? I ask because I want to use the new Test Support Library and UI Automator for testing. However, this is only available on API 18+. At the same time, I still want to support older versions of Android, albeit not as thoroughly tested. What do I need to add to my build.gradle
file in order to do this?
To clarify, I am using Android Studio and the "new" Gradle-based project structure.
Android Solutions
Solution 1 - Android
I got this from the new testing template from Google.
Create a new AndroidManifest.xml
file in your test
or androidTest
folder.
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:tools="http://schemas.android.com/tools"
package="your.package.name">
<uses-sdk tools:overrideLibrary="android.support.test.uiautomator.v18"/>
</manifest>
Solution 2 - Android
try this one.
defaultConfig {
applicationId "com.test"
if (gradle.startParameter.taskNames.contains(":app:assembleDebug")) {
minSdkVersion 21
}else{
minSdkVersion 14
}
targetSdkVersion 22
versionCode Integer.parseInt(VERSION_CODE)
versionName VERSION_NAME
}
updated 2020-04-16
You can also set with productFlavors
android {
compileSdkVersion 29
defaultConfig {
applicationId "com.test"
targetSdkVersion 29
versionCode 1
versionName "1.0.0"
}
buildTypes {
debug {
}
release {
minifyEnabled true
}
}
flavorDimensions "default"
productFlavors {
development {
minSdkVersion 21
}
production {
minSdkVersion 16
}
}
}
Solution 3 - Android
I've uploaded an example of the solution to mauricegavin/android-testing as I couldn't find a working one myself.
The module of interest is ui/uiautomator/BasicSample/app. You'll notice that there is an AndroidManifest.xml in the androidTests directory. The minSdkVersion
you specify in your app/build.gradle
will still be used for debug
and release
builds.
You'll see that the minSdkVersion
in the sample project's build.gradle specifies api 17
which is not supported by uiautomator and would usually cause the build to fail.
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:tools="http://schemas.android.com/tools"
package="com.example.android.testing.uiautomator.BasicSample" >
<uses-sdk tools:overrideLibrary="android.support.test.uiautomator.v18"/>
</manifest>
Thanks to mattblang for his answer which I used for this example.
Solution 4 - Android
I got the following conflict, for testing i needed a higher minSdkVersion.
The solution i found was taken from the following document using the buildType change the test build type and it did the job for me
The following is the solution:
android {
defaultConfig {
applicationId "com.doronkettner.ilikemovies"
...
minSdkVersion 18
...
testBuildType "staging"
...
}
...
buildTypes {
release {...}
debug {...}
staging {
initWith(buildTypes.debug) // keep versionName and PIN from 'debug'
defaultConfig.minSdkVersion 19
}
}
Change the buildType to stage and it should be ok
Solution 5 - Android
With androidx you can force usage of UI automator in version < 18 with tools:overrideLibrary="android_libs.ub_uiautomator"
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:tools="http://schemas.android.com/tools" package="..." >
<uses-sdk tools:overrideLibrary="android_libs.ub_uiautomator"/>
</manifest>
But it may lead to runtime failures if you are running your tests on version < 18
Solution 6 - Android
When you run androidTest there will be a task containing "AndroidTest"
at the end. That's why I filter my tasks based on this pattern.
My task name was - :app:assembleMyFlavourDebugAndroidTest
.
defaultConfig {
gradle.startParameter.taskNames.each {
if (it.contains("AndroidTest")) {
minSdkVersion 18
} else {
minSdkVersion 16
}
}
}
Solution 7 - Android
Yes, you can. You should put test-specific manifest entries in src/androidTest/AndroidManifest.xml
. When building your tests the manifest merger will combine both manifests, but when building your app only the main AndroidManifest.xml will be used.
See this answer for more details.
Solution 8 - Android
This is the hackiest version. It took me almost a day to create this script. Please take note of this for keepsake, but only use this as a last resort.
android.applicationVariants.all { variant ->
//Making specific variant disablements for faster build
if (variant.buildType.name.contains("debug")) {
println "Making min version to 21 and disabling multidex"
variant.mergedFlavor.setMultiDexEnabled false
def versionMin = new com.android.builder.core.DefaultApiVersion(21)
variant.mergedFlavor.setMinSdkVersion versionMin
}
}
Solution 9 - Android
After posting this question, I also had the idea to set minSdkVersion
to different values for the debug
and release
builds. However, I haven't had a chance to test if this works or not.
I also found one possible work around from this blog post. Create separate test
and production
flavors:
productFlavors {
// The actual application flavor
production {
minSdkVersion 14
}
// Test application flavor for uiautomatior tests
test {
minSdkVersion 18
}
}
Solution 10 - Android
@Code-Apprentice is almost there. But you can not name a product flavor to "test", "androidTest" or "release". They are like keyword, and you cannot use these names.
So the answer is
productFlavors {
product{
minSdkVersion 15
}
uiautoTest {
minSdkVersion 18
}
}
Solution 11 - Android
My solution based on flavor configuration:
> 1. split to two flavor:
buildTypes {
release {...}
debug {...}
}
productFlavors {
dev { ... }
autoTest {
minSdkVersion 18 // set to 18 only in this flavor
multiDexEnabled true // if you got dex index overflow error
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
}
}
> 2. move your test related dependencies into "autoTestCompile"
// for test
autoTestCompile 'com.android.support.test:runner:0.5', {
exclude group: 'com.android.support', module: 'support-annotations'
}
autoTestCompile 'com.android.support.test:rules:0.5', {
exclude group: 'com.android.support', module: 'support-annotations'
}
autoTestCompile 'com.android.support.test.espresso:espresso-web:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
}
autoTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
exclude group: 'com.android.support', module: 'support-v4'
exclude group: 'com.android.support', module: 'design'
exclude group: 'com.android.support', module: 'recyclerview-v7'
}
autoTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2', {
exclude group: 'com.android.support', module: 'support-annotations'
}
> 3. Run Test