当前位置: 首页 > 知识库问答 >
问题:

在可执行JAR中使用Maven在Springboot中运行Cucumber

乌靖
2023-03-14

各位工程师,大家好!

我在试图创建一个胖罐子来执行cucumber测试时遇到了一个问题。最初,我按照指南从Baeldung设置测试。当在Maven测试阶段执行时,测试运行良好。当运行带有参数的mvn exec:java命令时,它也能正常工作。

然而,当我创建了一个胖罐子并试图执行测试时,我面临着错误

java.util.concurrent.ExecutionException: io.cucumber.core.backend.CucumberBackendException: Please annotate a glue class with some context configuration.

For example:

   @CucumberContextConfiguration
   @SpringBootTest(classes = TestConfig.class)
   public class CucumberSpringConfiguration { }
Or:

   @CucumberContextConfiguration
   @ContextConfiguration( ... )

以下是我的项目的解释,它基本上与Baeldung的测试项目完全一样。

项目结构

package com.ing.testsuite;

import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
import org.springframework.context.annotation.Configuration;
import io.cucumber.*;


@RunWith(Cucumber.class)
@CucumberOptions(features="src/test/resources", glue="com.ing.testsuite", plugin = {"pretty","html:target/cucumber.html"})
class RunCucumberTest {

    public static void main(String[] args) throws Throwable {
        String[] arguments = {"classpath:dummy.feature", "classpath:com.ing.testsuite"};
        io.cucumber.core.cli.Main.main(arguments);
    }
}
package com.ing.testsuite;

import io.cucumber.spring.CucumberContextConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;

@CucumberContextConfiguration
@SpringBootTest(classes = RunCucumberTest.class)
public class CucumberSpringConfiguration{
}
package com.ing.testsuite;

import static org.junit.jupiter.api.Assertions.assertEquals;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;

public class StepDefinitions extends CucumberSpringConfiguration{

    private Integer noOfCucumbers;
    private Integer noOfCucumberEaten;
    private Integer noOfRemainingCucumber;

    @Given("There are {int} cucumbers")
    public void cucumberTest_nrOne(Integer noOfCucumber) throws Throwable{
        noOfCucumbers = noOfCucumber;
    }

    @When("I eat {int} cucumbers")
    public void cucumberTest_nrTwo(Integer noOfCucumberEaten) throws Throwable{
        noOfCucumbers = noOfCucumbers - noOfCucumberEaten;
    }

    @Then("I should have {int} cucumbers")
    public void cucumberTest_nrThree(Integer noOfRemainingCucumber) throws Throwable{
        assertEquals(noOfCucumbers,noOfRemainingCucumber);
    }


}
Feature: This is dummy test scenario
  Scenario Outline: Eating
  Given There are <start> cucumbers
  When I eat <eat> cucumbers
  Then I should have <left> cucumbers

  Examples:
  | start | eat | left |
  |  12   |  5  |  7   |
  |  20   |  5  |  15  |
  |  30   |  5  |  25  |
<assembly
    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
    <id>fat-tests</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <useProjectArtifact>true</useProjectArtifact>
            <unpack>true</unpack>
            <scope>test</scope>
        </dependencySet>
    </dependencySets>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}/test-classes</directory>
            <outputDirectory></outputDirectory>
            <includes>
                <include>**/*.*</include>
               </includes>
            <useDefaultExcludes>true</useDefaultExcludes>
        </fileSet>
        <fileSet>
            <directory>${project.build.directory}/test-classes</directory>
            <outputDirectory></outputDirectory>
            <includes>
                <include>*.feature</include>
            </includes>
            <useDefaultExcludes>true</useDefaultExcludes>
        </fileSet>
    </fileSets>
</assembly>
  • 直接从可执行jar运行Cucumber测试
  • SpringRunner无法检测配置
  • jar文件中的Spring上下文
  • 将cucumber jvm从版本4升级到版本6时,是否需要额外的上下文配置
  • 执行TestRunner类时发生初始化错误

如果有人能帮助我,我将不胜感激。

共有1个答案

柯耀
2023-03-14

我刚刚遇到了与Gradle相同的问题。我试图从jar文件运行Cucumber测试,但收到了相同的错误。

在build.gradle我添加了下一个代码:

 shadowJar {
     ....
     transform(AppendingTransformer) {
        resource = 'META-INF/services/io.cucumber.core.backend.BackendProviderService'
     }
 }

Maven中的类比类似于:

<transformers>
    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
        <resource>META-INF/services/io.cucumber.core.backend.BackendProviderService</resource>
    </transformer>
</transformers>

经过一段时间的调试(感谢Yulia)我们发现了cucumber是如何寻找Glue的(Glue类是cucumber运行所需的所有类——step def类,contextconfigurator,...).

它寻找那些具有后端服务的类,这些类的实例是在某个时候创建的。

在成功的案例中,实例化了2个服务:

  • io.cucumber.java。JavaBackendProviderService
  • io.cucumber.spring.SpringBackend提供商服务

在失败的情况下(通过从jar调试运行发现),只有一个:

  • io.cucumber.html" target="_blank">java.JavaBackendProviderService

找到了要实例化的BackendService在该文件中的确切位置-META-INF/services/io.cucumber.core.backend.BackendProviderService。

打开jar文件显示,确实只列出了一个服务——Java。

没有实例化Spring后端服务意味着它找不到Spring组件。

这些文件来自cucumber库:

    < li >来自cucumber-java的java 《cucumber的Spring-Spring》

因此,它归结为我们的打包过程无法将这2个文件合并在一起,而是选择第一个文件而不是应用第二个文件。

当从IDE运行时,它们似乎被很好地合并了。

因此,添加上面的代码说打包任务(在我的情况下是shadowJar)如何处理此文件,添加一个规则来合并所有具有它将找到的具有此名称的文件(当然在META-INF中)。

我希望你已经解决了你的问题,如果没有——我希望我的经验也能帮助你解决问题。

 类似资料:
  • 问题内容: 我在将当前项目提取到可执行jar文件时遇到问题。当我在日食中按下运行按钮时,一切正常,但是当我这样做时 然后启动.jar文件;我唯一得到的是带有灰色画布的窗口。它应该启动我编写的游戏(spaceInvaders)。 这是我上载项目的github的链接。我真的不知道错误在哪里,在哪里看。在我的代码中?在我安装的JRE / JDK中?创建罐子时我做错什么了吗? 请帮忙 -。- 问题答案:

  • 我在Eclipse中有一个maven项目。在src/main/resources下,我有一个名为“directoryToCopy”的目录,其中包含文件。一旦我运行了我的项目,我想将“directoryToCopy”复制到桌面上的本地目录“localDirec”下。 我用了这个: 这在本地工作正常,但是当我想将其作为可执行jar文件运行时,我会得到NullPointerException。 请问有什

  • 我试图用scala和Maven创建可执行jar。我正在使用maven-scala-plugin和maven-assembly-plugin,但在我看来,汇编插件被忽略了。我得到没有依赖项的jar和包含没有主类行的manifest。

  • 我正在使用org.codehaus.mojo exec-maven-plugin通过我的pom.xml项目执行一个可执行的。jar文件。目前这不起作用,我不确定为什么。当我指定CommandLineArgs时会发生错误。 我的插件如下所示:

  • 我有一个在eclipse和cmd提示符中运行良好的Jar。当我尝试在Unix中执行相同的程序时,它没有执行。

  • 问题内容: 我有一个多模块Maven项目,其中一个模块用于分发。 该发行版包含一个我想轻松执行的可执行jar。但是,要执行它,我必须键入类似以下内容: 简单键入以下内容将是更好的选择: 不幸的是,我找不到找到执行.jar的java目标的方法。exec目标实际上可以做到,但是有一个陷阱:jar包含一个嵌入式码头服务器,并且由于exec的工作方式(不使用与maven相同的JVM),除非我杀死进程,否则