I'm trying to do this, but with a single dimension so it's simpler: How to specify unit test folder in two-dimension flavor
app module build.gradle specifies 2 flavors, free and premium:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.myapplication"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-
optimize.txt'), 'proguard-rules.pro'
}
}
flavorDimensions 'someFlavor'
productFlavors {
premium {
applicationIdSuffix '.premium'
}
free
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
debug.java.srcDirs += 'src/debug/kotlin'
release.java.srcDirs += 'src/release/kotlin'
free {
java.srcDirs += 'src/free/kotlin'
test.java.srcDirs += 'src/test/kotlin'
}
premium {
java.srcDirs += 'src/premium/kotlin'
test.java.srcDirs += ['src/test/kotlin',
'src/testPremium/kotlin']
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.android.support:design:28.0.0'
}
Android Studio's Project view shows:
app
src
free
kotlin (empty folder for now)
main
java
com.example.myapplication
MainActivity.java
premium
kotlin
com.example.myapplication
PremiumFile.kt
test
kotlin
com.example.myapplication
MainTest.kt
testPremium
kotlin
com.example.myapplication
PremiumTest.kt
PremiumFile.kt
class PremiumFile {
companion obnject {
const val PREMIUM_NUM = 10
}
}
MainTest.kt
class MainTest {
@Test
fun basicMainTest() {
assertEquals(1, 1)
}
}
PremiumTest.kt
class PremiumTest {
@Test
fun premiumTest() {
assertEquals(PremiumFile.Premium_NUM, 1)
}
}
As you can see, I lack any unit tests specific to the free flavor. I expected that running ./gradlew compileFreeReleaseUnitTestKotlin would compile the shared unit test inside src/test, but it also compiles the Premium unit tests inside src/testPremium. How can I make sure that PremiumTest.kt is only compiled for Premium tasks such as ./gradlew compilePremiumReleaseUnitTestKotlin?
Build variants are the result of Gradle using a specific set of rules to combine settings, code, and resources configured in your build types and product flavors. Although you do not configure build variants directly, you do configure the build types and product flavors that form them.
Flavor dimensions are groupings of product flavors, and you can combine flavors from different dimensions.
A build type determines how an app is packaged. By default, the Android plug-in for Gradle supports two different types of builds: debug and release . Both can be configured inside the buildTypes block inside of the module build file.
Change the build variant By default, Android Studio builds the debug version of your app, which is intended for use only during development, when you click Run. To change the build variant Android Studio uses, select Build > Select Build Variant in the menu bar.
If you run gradlew sourceSets on your project, you'll get the following section among the others :
test
----
Compile configuration: testCompile
build.gradle name: android.sourceSets.test
Java sources: [app\src\test\java, app\src\test\kotlin, app\src\testPremium\kotlin]
Java-style resources: [app\src\test\resources]
testPremium
-----------
Compile configuration: testPremiumCompile
build.gradle name: android.sourceSets.testPremium
Java sources: [app\src\testPremium\java]
Java-style resources: [app\src\testPremium\resources]
As you can see app\src\testPremium\kotlin is in the main test configuration, not in the testPremium. And because test is shared among all the flavors, its sources included in all of them (e.g. testFree configuration will include sources specified in both test and testFree configurations).
It also suggests you how to fix the issue - use testPremium in the configuration block. So instead of
premium {
java.srcDirs += 'src/premium/kotlin'
test.java.srcDirs += ['src/test/kotlin', 'src/testPremium/kotlin']
}
Write
premium {
java.srcDirs += 'src/premium/kotlin'
}
test{
java.srcDirs += 'src/test/kotlin'
}
testPremium {
java.srcDirs += 'src/testPremium/kotlin'
}
So gradlew sourseSets will give you:
test
----
Compile configuration: testCompile
build.gradle name: android.sourceSets.test
Java sources: [app\src\test\java, app\src\test\kotlin]
Java-style resources: [app\src\test\resources]
testPremium
-----------
Compile configuration: testPremiumCompile
build.gradle name: android.sourceSets.testPremium
Java sources: [app\src\testPremium\java, app\src\testPremium\kotlin]
Java-style resources: [app\src\testPremium\resources]
Because test does not exist in AndroidSourceSet, it's not a 'type' of sources like 'java', 'resources' and so on. Instead, test is another instance of AndroidSourceSet. So when you're writing test.java.srcDirs, you are actually configuring this top-level test source set, not tests inside premium.
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