Is there a flag to have tests print the name of th...
# kotlin-native
l
Is there a flag to have tests print the name of the current running test? I’m seeing one test infinitely loop on one of my laptops, but all I can see is
:modulename:iosSimulatorArm64Test > 122 tests completed
. I’d like to know which test is currently running. If I run in the IDE, where it does show the current test, no tests infinite loop.
If I run
./gradlew :modulename:iosSimulatorArm64Test --debug
, it looks like it prints the name when each test runs, but I have to search through a lot of output to find it. It would be nice to have a --printNames or something.
k
The
testLogging
feature of gradle might be what you need.
Copy code
tasks.withType<AbstractTestTask> {
    testLogging { /* stuff */ }
}
This won’t show the name of the tests, but you might be able to do it with
Copy code
tasks.withType<AbstractTestTask> {
    testLogging { 
        events(TestLogEvent.STARTED)
    }
}
The docs for that option are here.
Copy code
/**
 * Test events that can be logged.
 */
public enum TestLogEvent {
    /**
     * A test has started. This event gets fired both for atomic and composite tests.
     */
    STARTED,
This took me a while to figure out when I needed to pipe stdout from tests for debugging purposes, so I hope this helps you
I don’t know what gets logged with
STARTED
though 😢
e
minor nit:
withType(action)
configures eagerly, use
withType().configureEach(action)
instead
also for convenience you can write
Copy code
testLogging {
    events("started", "passed", "skipped", "failed")
}
instead of having to import
TestLogEvent.*
note: I've only ever run Kotlin/Native host tests, not simulator tests, so I'm not totally confident it'll work the same way… but hopefully
l
In that case, should I change my code that configures ios tests too?
Copy code
val iosTestTasks = arrayOf("iosX64Test", "iosArm64Test", "iosSimulatorArm64Test").mapNotNull {
    tasks.findByName(it)
}

iosTestTasks.forEach {
    ...
}
k
Targeting AbstractTestTask should capture all tests though, right?
e
KotlinNativeSimulatorTest is a KotlinNativeTest is a KotlinTest is a AbstractTestTask, so yes,
withType<AbstractTestTask>()
will get them all
k
I feel like the default information for K/N tests is not configured very well. It doesn’t even report stacktraces unless you tell it to.
Until I configured my tests to report the backtrace, I would get a something like
test failure -null
e
Kotlin's test tasks don't change Gradle's defaults as far as I'm aware
k
Right. I feel like that can be a bit counterintuitive for someone coming from JUnit which has sane defaults.
l
I’ll have to mess around with the config more. I’m not even getting stdout.
k
std is this:
Copy code
testLogging {
        showStandardStreams = true
    }
Note that it won’t report stdout in realtime, only after a test has finished.
Which is a bummer.
l
I guess that won’t be as helpful for the test that’s infinite looping then.
k
Exactly.
e
you can add the
TestLogEvent.STANDARD_OUT
and
TestLogEvent.STANDARD_ERROR
events
k
Will that report in realtime?
l
It looks like it does based on the logs from --debug.
e
I'm not sure. there's definitely still buffering but I don't remember writing any infinite tests
k
I’ll have to play with it later.
I had the exact same problem @Landry Norris was having, an infinite loop somewhere which was hard to isolate because unit tests didn’t pipe stdout until a test finished or failed.
l
I think it’s to do with a synchronized block. When I got logs in --debug, it seems like it was never able to acquire the lock.
k
So I ended up peppering in random
error("Got here")
which felt really nooby lol
e
if you're having that issue, you can configure
timeout
on any task, including test tasks
l
Not sure if it’s a bug in atomicfu or what, but it passes on CI so 🤷