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