我尝试为我的 cucumber kotlin 应用程序创建一个可执行 jar,但它在日志中打印出所有场景都未定义:
...
3 Scenarios (3 undefined)
8 Steps (5 skipped, 3 undefined)
...
应用程序可以从命令行或IntelliJ正确执行
程序入口点:
package dsdms.client
import io.cucumber.core.cli.Main
class Main{
companion object{
@JvmStatic
fun main(args: Array<String>) {
Main.main("-p", "pretty",
"--glue", "dsdms.client.cucumber",
"--plugin", "html:build/reports/cucumber",
"classpath:features")
println("Hello Worldddd2!")
}
}
}
对于项目构建,我将 Gradle 与 kotlin DSL 结合使用
我尝试先使用
src/test
,然后使用src/main
文件夹,但即使我可以从控制台正确执行所有内容,它也不适用于jar执行
对于我使用的 fat jar 生成:
tasks.withType<Jar> {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest {
attributes["Main-Class"] = "dsdms.client.Main"
}
dependsOn(configurations.runtimeClasspath)
from({
configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) }
})
destinationDirectory.set(file("$buildDir/output"))
}
这里链接到重现我的问题的存储库。它还包含一个由项目生成的 jar 文件
创建 jar 文件时,您已设置
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
因此任何重复文件都将被忽略。
如果你设置:
duplicatesStrategy = DuplicatesStrategy.WARN
你会看到:
> Task :SystemTester:jar
Encountered duplicate path "META-INF/versions/9/module-info.class" during copy operation configured with DuplicatesStrategy.WARN
Encountered duplicate path "META-INF/services/io.cucumber.core.backend.BackendProviderService" during copy operation configured with DuplicatesStrategy.WARN
Encountered duplicate path "META-INF/versions/9/module-info.class" during copy operation configured with DuplicatesStrategy.WARN
Encountered duplicate path "META-INF/versions/9/module-info.class" during copy operation configured with DuplicatesStrategy.WARN
这些警告很重要!要理解为什么理解这些文件的作用很重要。所以值得阅读JAR 文件规范.
但简而言之,对于您的问题,这是重要的警告:
Encountered duplicate path "META-INF/services/io.cucumber.core.backend.BackendProviderService" during copy operation configured with DuplicatesStrategy.WARN
因为如果你查看你的依赖项,你会发现你有:
[libraries]
cucumber-java = {module = "io.cucumber:cucumber-java", version.ref="cucumber"}
...
cucumber-java8 = {module = "io.cucumber:cucumber-java8", version.ref="cucumber"}
两者都包含
META-INF/services/io.cucumber.core.backend.BackendProviderService
文件。
对于
cucumber-java
此文件包含:
io.cucumber.java.JavaBackendProviderService
而对于
cucumber-java8
它包含:
io.cucumber.java8.Java8BackendProviderService
这些告诉 Cucumber 它有哪些服务可用于检测步骤定义(即它让 Cucumber 使用注释或 lambda 知道你)`。
现在,如果您解压缩您制作的 jar 文件(您可以使用您最喜欢的 zip 应用程序执行此操作),您会发现它只包含
BackendProviderService
cucumber-java
的注册,而不是 cucumber-java8
的注册。因此,您的步骤定义未加载,因为 Cucumber 不理解 lambda 步骤定义。
解决此问题的快速但错误的方法是删除
cucumber-java
作为依赖项。但是您可能会遇到其他类似性质的问题。所以你最好的选择是扩展你的 Gradle 任务来合并META-INF/services
文件。
如何?一点线索也没有。我不使用 Gradle。