Cucumber 可执行 jar 有未定义的场景

问题描述 投票:0回答:1

我尝试为我的 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 文件似乎包含执行所需的所有文件 screenshot of jar file in zip format

Gradle module structure

这里链接到重现我的问题的存储库。它还包含一个由项目生成的 jar 文件

jar cucumber build.gradle cucumber-jvm gradle-kotlin-dsl
1个回答
0
投票

创建 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。

© www.soinside.com 2019 - 2024. All rights reserved.