Set different minSdkVersion for testAndroid than for main app

AndroidTestingAndroid Uiautomator

Android 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

Build Variant Screenshot

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCode-ApprenticeView Question on Stackoverflow
Solution 1 - AndroidtheblangView Answer on Stackoverflow
Solution 2 - AndroidSoo Chun JungView Answer on Stackoverflow
Solution 3 - AndroidMaurice GavinView Answer on Stackoverflow
Solution 4 - AndroiddogoodView Answer on Stackoverflow
Solution 5 - AndroidStéphaneView Answer on Stackoverflow
Solution 6 - AndroidSattar HummatliView Answer on Stackoverflow
Solution 7 - AndroidAllen HairView Answer on Stackoverflow
Solution 8 - AndroidPier BetosView Answer on Stackoverflow
Solution 9 - AndroidCode-ApprenticeView Answer on Stackoverflow
Solution 10 - AndroidsongzhwView Answer on Stackoverflow
Solution 11 - AndroidLin Yu ChengView Answer on Stackoverflow