I'm trying to set jvmargs for unit tests using kotlin-dsl and I can't get it to work.
This is so that I can add the "-noverify" argument and allow intellji test runner to collect code coverage info.
Groovy, works:
testOptions {
unitTests.all {
jvmArgs '-noverify'
}
}
Kotlin, doesn't work:
testOptions {
unitTests.all(KotlinClosure1<Any, Test>({
(this as Test).also { jvmArgs("-noverify") }
}, this))
}
This too:
testOptions {
unitTests.all(KotlinClosure1<Any, Test>({
(this as Test).also { jvmArgs = listOf("-noverify") }
}, this))
}
Nothing seems to work, what am I missing?
I was having the same issue. The following snippet works.
tasks.withType<Test>().all {
jvmArgs("-noverify")
}
Ref - https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/testing/Test.html#jvmArgs-java.lang.Object...-
Verified using Gradle-5.1.-all version
This question is a little old but wanted to post an updated Kotlin DSL version for 2021:
testOptions.unitTests.all { it.jvmArgs("-noverify") }
Related
During migration build script from groovy to kotlin I met problem with excluding build variants.
In groovy it's pretty easy:
android {
variantFilter { variant ->
if (variant.name == "lorempisum") {
setIgnore(true)
}
}
}
but in kotlin similar thing does not work. It seems to be ok in android studio, but during compilation it throws Unresolved reference: isIgnore
android {
variantFilter {
if (buildType.name == "lorempisum") {
isIgnore = true
}
}
}
from the other side this reports Unresolved reference: setIgnore, but works during compilation
android {
variantFilter {
if (buildType.name == "lorempisum") {
this.setIgnore(true)
}
}
}
Anybody has idea how do it in right way?
I'm using kotlin 1.3.72, android studio 4.0.1 and gradle 6.5.1
---- EDIT ----
I fix example ignore -> isIgnore in second block, it also not works
Soultion is ignore = true with a little deatil.
This works if you keep in top-level build.gradle.kts this line:
classpath("com.android.tools.build:gradle:4.0.1")
and not really only on buildSrc on this:
implementation("com.android.tools.build:gradle:4.0.1")
Use the beforeVariants block:
androidComponents {
beforeVariants { variantBuilder ->
// To check for a certain build type, use variantBuilder.buildType == "<buildType>"
if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) {
// Gradle ignores any variants that satisfy the conditions above.
variantBuilder.enabled = false
}
}
}
You should first update to the last version of android studio and the plugins.
And try this
variantFilter {
this.ignore = name == "lorempisum"
}
I am trying to use Android logs in my shared code so wanted to make use of the 'expected/actual' functionality in order to make the android side use logs to be read in log cat. However I cannot get the android module(not app module) to import the android.util.Log.
I have seen this answer but it did not work for me. I cannot get the import to resolve.
I think I need to implement a specific dependency in order to have access to the import but I'm not sure what that is.
Here is my build.gradle.kts
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
plugins {
kotlin("multiplatform")
}
kotlin {
//select iOS target platform depending on the Xcode environment variables
val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
::iosArm64
else
::iosX64
iOSTarget("ios") {
binaries {
framework {
baseName = "SharedCode"
}
}
}
jvm("android")
sourceSets["commonMain"].dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
implementation("io.ktor:ktor-client:1.0.0-beta-3")
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.3.2")
// implementation ("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:0.14.0")
}
sourceSets["androidMain"].dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib") //Allows _androidMain to have java imports
implementation("io.ktor:ktor-client-android:1.0.0-beta-3")
api("org.jetbrains.kotlin:kotlin-stdlib:1.3.61")
api("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.61")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61")
}
}
val packForXcode by tasks.creating(Sync::class) {
val targetDir = File(buildDir, "xcode-frameworks")
/// selecting the right configuration for the iOS
/// framework depending on the environment
/// variables set by Xcode build
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
val framework = kotlin.targets
.getByName<KotlinNativeTarget>("ios")
.binaries.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
from({ framework.outputDirectory })
into(targetDir)
/// generate a helpful ./gradlew wrapper with embedded Java path
doLast {
val gradlew = File(targetDir, "gradlew")
gradlew.writeText("#!/bin/bash\n"
+ "export 'JAVA_HOME=${System.getProperty("java.home")}'\n"
+ "cd '${rootProject.rootDir}'\n"
+ "./gradlew \$#\n")
gradlew.setExecutable(true)
}
}
tasks.getByName("build").dependsOn(packForXcode)
Here you got JVM target with the name "android" instead of actually Android target. The same problem occurred in the linked question. Can you tell, what's going on when you use the script from the answer? It seems like that one should work correctly.
As described in the documentation, one has to use an Android-specific Gradle plugin to make the Android target available. If you want to see how it can be done, consider having a look at this sample.
I had the same problem. Try using android() instead of only the jvm("android").
Also I've added my dependencies to android with android.sourceSets.foreach{ _ ->
dependencies{ ... }
}
Just fixed same issue, finally used this tutorial https://medium.com/icerock/how-to-start-use-kotlin-multiplatform-for-mobile-development-1d3022742178
so my build.gradle looks like:
apply plugin: 'com.android.library'
apply plugin: 'org.jetbrains.kotlin.multiplatform'
android {
compileSdkVersion 29
defaultConfig {
minSdkVersion 14
targetSdkVersion 29
}
}
kotlin {
targets {
android()
iosArm64()
iosX64()
}
sourceSets {
commonMain {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version"
}
}
androidMain {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
}
}
}
Here is my build.gradle.kts :
import org.jetbrains.kotlin.config.KotlinCompilerVersion
plugins {
...
}
android {
compileSdkVersion(27)
defaultConfig {
...
}
buildTypes {
...
}
sourceSets {
getByName("main").java.srcDirs("src/main/java", "src/main/kotlin")
getByName("test").java.srcDirs("src/test/java", "src/test/kotlin")
getByName("androidTest").java.srcDirs("src/androidTest/java", "src/androidTest/kotlin")
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
dependencies {
implementation(kotlin("stdlib-jdk7", KotlinCompilerVersion.VERSION))
implementation("com.android.support:appcompat-v7:27.1.1")
...
//Test
testImplementation("org.junit.jupiter:junit-jupiter-api:5.1.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.1.1")
androidTestImplementation("com.android.support.test:runner:1.0.2")
androidTestImplementation("com.android.support.test.espresso:espresso-core:3.0.2")
androidTestImplementation("android.arch.core:core-testing:1.1.1")
testImplementation("io.kotlintest:kotlintest-runner-junit5:3.1.10")
testImplementation("io.mockk:mockk:1.8.7")
}
When building it with ./gradlew build no error occurs but if I use the specified codefrom the doc :
val test by tasks.getting(Test::class) {
useJUnitPlatform { }
}
I get the following error : Task with name 'test' not found in project ':app'.
My settings.gradle.kts:
include(":app")
Does anyone know what's going on here? It's weird AS can suggest me autocompletion and all but while compiling, I get this unresolved reference.
Looks like your issue is with this block,
tasks.withType<Test> {
useJUnitPlatform()
}
If you're not using test task then you can simply remove that
code and that error will be gone !
Edit:
If you want to use test task. try like this in project level build.gradle,
tasks.register("test", Test::class) {
useJUnitPlatform()
}
I have found little glitch in crashlytics/fabric setup in gradle which took 2 hours of my poor life.
first of all i did everything they said in this guide:
https://fabric.io/kits/android/crashlytics/install
and here is the piece of code which everything caused:
First try
dependencies {
...
compile('com.crashlytics.sdk.android:crashlytics:2.9.4#aar') {
transitive = true;
}
}
every library version in dependencies{} block iam using ext{} block in appname/app/build.gradle so in our case
ext {
crashlytics = '2.9.4#aar'
}
so in the end it will be like this only change implementation which should be there in my opinion because it will be deprecated at end of 2018. implementations doenst change any behavior.
implementation("com.crashlytics.sdk.android:crashlytics:$crashlytics"){
transitive = true
}
but if u try to build this u gonna get:
No such property: betaDistributionApkFilePath for class: java.lang.String
wow. i have no idea why.. but lets investigate this. we will try different setup so forget everyting you saw above.
Second try
in our appname/app/build.gradle in dependencies{} change our lane to this so we have no ext{} for version
implementation("com.crashlytics.sdk.android:crashlytics:$rootProject.ext.crashlytics") {
transitive = true
}
and now in our root gradle appname/build.gradle
buildscript {
ext.fabric_gradle = '2.9.4#aar'
repositories {
...
}
dependencies {
...
}
}
Build is OK you can continue to work. But what? Its should be completely the same...
Third try
I dont know why but in our first try u just CANT in appname/app/build.gradle ext{} block name crashlytics variable it have to very everything else except crashlytics for instance crashlytics_version so lets make first try to working state.
ext {
crashlytics_version = '2.9.4#aar'
}
implementation("com.crashlytics.sdk.android:crashlytics:$crashlytics_version"){
transitive = true
}
Build is OK. Magic.
or just do it in normal way and dont try to make smart things.... As first block of code in this long investigation which works also completely fine:
compile('com.crashlytics.sdk.android:crashlytics:2.9.4#aar') {
transitive = true;
}
You just CANT in appname/app/build.gradle ext{} block name your variable crashlytics it have to be everything else except crashlytics for instance crashlytics_version so:
ext {
crashlytics_version = '2.9.4#aar'
}
implementation("com.crashlytics.sdk.android:crashlytics:$crashlytics_version"){
transitive = true
}
Build is OK.
or just do it in normal way:
compile('com.crashlytics.sdk.android:crashlytics:2.9.4#aar') {
transitive = true;
}
I need a very simple way to get Robolectric 3.0 to turn on logging. I want to see the output from robolectric, not just my tests. Everything I tried off the web is not working.
Where do I stick this?
robolectric.logging.enabled = true
I tried the following:
In a robolectric.properties file in test/java/res
In a robolectric.properties file in test/java/resources
In a robolectric.properties file in test/res
In a robolectric.properties file in test/resources
In gradle:
afterEvaluate {
project.tasks.withType(Test) {
systemProperties.put('robolectric.logging.enable', 'true')
}
}
In gradle:
tasks.withType(Test) {
testLogging.exceptionFormat = 'full'
systemProperties.put('robolectric.logging.enable', 'true')
}
You can add to your tests:
#Before
public void init() {
ShadowLog.stream = System.out;
}
then use: gradle test -i
Source: Unable to get log.d or output Robolectrict + gradle
or Add in the build.gradle:
tasks.withType(Test) {
systemProperty "robolectric.logging", "stdout"
}
Source: https://github.com/studyplus/Studyplus-Android-SDK/blob/master/StudyplusAndroidSDK/build.gradle#L41