如何从 StackTraceElement 创建 JUnit 5 DynamicTest testSourceUri?

How can I create a JUnit 5 DynamicTest testSourceUri from a StackTraceElement?

Minutest 允许即时生成 JUnit 5 DynamicTests。当在 IDE.

中单击测试时,我希望能够导航到生成测试的代码

documentation gives examples of URI's that can be used for this purpose. All I have at the point of test definition though is a StackTraceElement.

如何使用堆栈跟踪元素中的信息来构造合适的 URI?

我认为你能做的最好的事情就是根据 URI 模式MethodSource 定位

method:org.junit.Foo#bar(java.lang.String, java.lang.String[])

不过,这只会带您进入测试方法,这在 Minutest 的情况下并不是最佳的。

这是 IMO Java 语言的问题,而不是 JUnit 5 平台的问题。 Java 没有比指向方法更准确地获取代码位置(通过反射)的方法。一个例外是例外(双关语意)。异常的堆栈跟踪可以指向方法中的确切位置。这就是为什么 - 在断言失败的情况下 - 大多数 IDE 允许您导航到测试失败起源的行。

在像您这样的极少数情况下,您在测试定义时有一个可用的堆栈跟踪元素,JUnit 可以引入类似 FileLocationSource 的东西,并希望 IDE 供应商能够接受它 - 虽然他们还没有从 JUnit 5 API 中获取其他东西,这些东西已经存在了一段时间。您可能会考虑为 JUnit 5 创建一个 github 问题来说服他们。

我最终通过猜测源位置创建了一个文件 URI。

private fun StackTraceElement.toSourceFileURI(sourceRoot: File): URI? {
    val fileName = fileName ?: return null
    val type = Class.forName(className)
    val fileUri = sourceRoot.toPath().resolve(type.`package`.name.replace(".", "/")).resolve(fileName).toUri()
    return URI(fileUri.scheme, fileUri.userInfo, fileUri.host, fileUri.port, "//" + fileUri.path, "line=$lineNumber", fileUri.fragment)
}

给定 src/test/java 的 sourceRoot,这将生成一个 URI,当双击测试时,IntelliJ 能够遵循该 URI。