Martin
Martin

Reputation: 726

Configure testLogging for instrumented tests

I would like to configure testLogging for my instrumented tests. However, Gradle seems to ignore my configuration in android.testOptions.unitTests.all.testLogging. There, I have configured that all passed and failed tests should be logged, but skipped tests should be not logged. However, Gradle does not log my passed tests but does log my skipped test.

build.gradle:

plugins {
    id 'com.android.application'
}

android {
    compileSdk 31

    defaultConfig {
        applicationId 'com.example.myapplication'
        minSdk 26
        targetSdk 31
        versionCode 1
        versionName '1.0'

        testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    testOptions {
        unitTests {
            all {
                testLogging {
                    events = ["passed", "failed"]
                }
            }
        }
    }
}

dependencies {
    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    androidTestImplementation 'androidx.test:runner:1.4.0'
}

ExampleInstrumentedTest.java:

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import org.junit.Ignore;
import org.junit.Test;

public class ExampleInstrumentedTest {
    @Test
    public void passedTest() {
        assertEquals(2, 1 + 1);
    }

    @Test
    public void failedTest() {
        assertEquals(3, 1 + 1);
    }

    @Test
    @Ignore
    public void skippedTest() {
        fail("Should be skipped");
    }
}

Unfortunately, Gradle does not consider my test logging configuration. Besides my Gradle configuration, skipped tests are output, but passed tests are not output.

Output:

> Task :app:connectedDebugAndroidTest
Starting 3 tests on test(AVD) - 12

com.example.myapplication.ExampleInstrumentedTest > skippedTest[test(AVD) - 12] SKIPPED 

com.example.myapplication.ExampleInstrumentedTest > failedTest[test(AVD) - 12] FAILED 
    java.lang.AssertionError: expected:<3> but was:<2>
    at org.junit.Assert.fail(Assert.java:88)
Tests on test(AVD) - 12 failed: There was 1 failure(s).

I have hosted my complete minimal example project on GitHub: pmwmedia/android-test-example.

Upvotes: 5

Views: 873

Answers (3)

shubhamgarg1
shubhamgarg1

Reputation: 2005

You can pass -is argument while running the testing task. For e.g., run your tests using:

./gradlew -is connectedDebugAndroidTest

This should print out few logs like running, passed, failed, or skipped with each test case.

Upvotes: 0

natronite
natronite

Reputation: 897

It is possible with a bit of reflection and a custom class.

Not the best code, but something like this lets you customise the logging in some ways (with the AGP 7.4):

tasks.withType<com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask> {
    val field = javaClass.superclass.superclass.superclass.superclass.superclass.superclass.getDeclaredField("logger")
    field.isAccessible = true
    val defaultLogger = field.get(this)
    val delegate = defaultLogger.javaClass.getDeclaredField("delegate").apply { isAccessible = true }.get(defaultLogger) as Logger
    field.set(this, CustomInstrumentationTestsLogger(delegate))
 }
        
class CustomInstrumentationTestsLogger(delegate: Logger) :
       org.gradle.internal.logging.slf4j.DefaultContextAwareTaskLogger(delegate) {
       ...
}

You can then override isEnabled and log (or other) methods to switch up log levels for certain messages.

It's a dirty workaround, but it works.

Upvotes: 0

romtsn
romtsn

Reputation: 12002

Unfortunately, that's not possible, because connected${Variant}AndroidTest task does not inherit from Gradle's AbstractTestTask, therefore testOptions.unitTests will have no effect on android instrumented tests.

At this point you're out of luck, unless you somehow extend the Android's connected test task and implement your custom task which complements Gradle's testLogging extension.

You can check the task source here and this is where the actual logging happens here

Upvotes: 1

Related Questions