Skip to content

Commit

Permalink
Reinstate basic detection of JU5 annotation in stack trace strategy
Browse files Browse the repository at this point in the history
Turns out that kotlin.test defaults to JUnit 5 in certain applications
(e.g. Compose Desktop or Multiplatform) and the existing strategy
does pick up its method names correctly. Add a comment explaining the context
  • Loading branch information
mannodermaus committed May 13, 2024
1 parent 4f07c4b commit 0fd2f85
Showing 1 changed file with 24 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.takahirom.roborazzi

import org.junit.Test
import java.lang.reflect.Method

/**
* Default strategy for finding a suitable output name for [DefaultFileNameGenerator].
Expand All @@ -10,20 +11,20 @@ internal object StackTraceTestNameExtractionStrategy : TestNameExtractionStrateg
override fun extract(): Pair<String, String>? {
// Find test method name
val allStackTraces = Thread.getAllStackTraces()
val filteredTracces = allStackTraces
val filteredTraces = allStackTraces
// The Thread Name is come from here
// https://github.com/robolectric/robolectric/blob/40832ada4a0651ecbb0151ebed2c99e9d1d71032/robolectric/src/main/java/org/robolectric/internal/AndroidSandbox.java#L67
.filterKeys {
it.name.contains("Main Thread")
|| it.name.contains("Test worker")
}
val traceElements = filteredTracces
val traceElements = filteredTraces
.flatMap { it.value.toList() }
val stackTraceElement = traceElements
.firstOrNull {
try {
val method = Class.forName(it.className).getMethod(it.methodName)
method.getAnnotation(Test::class.java) != null
method.isJUnit4Test() || method.isJUnit5Test()
} catch (e: NoClassDefFoundError) {
false
} catch (e: Exception) {
Expand All @@ -35,4 +36,24 @@ internal object StackTraceTestNameExtractionStrategy : TestNameExtractionStrateg
it.className to it.methodName
}
}

private fun Method.isJUnit4Test(): Boolean {
return getAnnotation(Test::class.java) != null
}

// This JUnit 5 check works for basic usage of kotlin.test.Test with JUnit 5
// in basic Compose desktop and multiplatform applications. For more complex
// support including dynamic tests, [JUnit5TestNameExtractionStrategy] is required
@Suppress("UNCHECKED_CAST")
private val jupiterTestAnnotationOrNull = try {
Class.forName("org.junit.jupiter.api.Test") as Class<Annotation>
} catch (e: ClassNotFoundException) {
null
}

@Suppress("USELESS_CAST")
private fun Method.isJUnit5Test(): Boolean {
return (jupiterTestAnnotationOrNull != null &&
(getAnnotation(jupiterTestAnnotationOrNull) as? Annotation) != null)
}
}

0 comments on commit 0fd2f85

Please sign in to comment.