【问题标题】:Glue code is not loaded when running with cucumber-spring back-end from jar file使用 jar 文件中的 cucumber-spring 后端运行时未加载胶水代码
【发布时间】:2019-07-07 08:47:01
【问题描述】:

我一直在尝试使用 Junit(4.12)、Cucumber-Java(4.1.1)、Cucumber-Spring(4.1.1) 和 Cucumber-Junit(4.1.1) 的组合运行基于 spring 的黄瓜测试)。 从 IDE(IntelliJ 2018.3.4)内部运行测试时加载胶水代码没有问题,但似乎由于某种原因,当我尝试从编译的 jar 文件(在这种情况下是必需的)运行时,黄瓜没有' t 找到步骤定义。

我已经尝试过多种粘合代码格式,例如: “类路径:com.a.b.c.stepdefs” “com.a.b.c.stepdefs” “类路径:com/a/b/c/stepdefs”

我还尝试提供从 runner 类到 step 定义类的相对路径(仅嵌套在下面一层) “步骤定义”

还尝试使用 JUnit 和 cucumber.cli.Main 运行,并尝试使用不同样式的步骤定义(黄瓜表达式 - 缺少步骤 sn-ps 指向我 - 和正则表达式)

我正在使用 spring-boot-maven-plugin,所以我知道这通常会改变 jar 结构

从 IDE 运行时,上述所有变体都可以完全工作,但不能从 jar 文件运行

主类:

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@ComponentScan(basePackages = {"com.a.b.test.core.data",
    "com.a.b.c",
    "com.a.b.c.stepdefs"}
)
public class CucumberApplication {

    public static void main(String[] args) throws IOException, InterruptedException {

        SpringApplication.run(CucumberApplication.class, args);

        Result result = JUnitCore.runClasses(RunnerCentral.class);
        System.exit(result.wasSuccessful() ? 0 : 1);

    }
}

跑步者类:

package com.a.b.c;

@RunWith(Cucumber.class)
@CucumberOptions(features = "classpath:BOOT-INF/classes/features",
glue = "classpath:com/a/b/c/stepdefs",
plugin = "json:target/cucumber-html-reports/cucumber.json")
public class RunnerCentral {
}

spring-boot-maven-plugin 的 POM 配置:

  <plugin>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-maven-plugin</artifactId>
     <version>2.1.0.RELEASE</version>
         <configuration>
             <fork>true</fork>
             <mainClass>${start-class}</mainClass>
             <requiresUnpack>
                 <dependency>
                     <groupId>io.cucumber</groupId>
                     <artifactId>cucumber-java</artifactId>
                 </dependency>
                 <dependency>
                     <groupId>io.cucumber</groupId>
                     <artifactId>cucumber-spring</artifactId>
                 </dependency>
                 <dependency>
                     <groupId>io.cucumber</groupId>
                     <artifactId>cucumber-junit</artifactId>
                 </dependency>
             </requiresUnpack>
         </configuration>
         <executions>
             <execution>
                 <goals>
                     <goal>repackage</goal>
                 </goals>
             </execution>
         </executions>
     </plugin> 

我希望从 IDE 运行和从打包源运行之间的行为是一致的,尽管我可能会遗漏一些东西

我要提到的另一件事是,当用 cucumber-picocontainer 交换后端时,一切似乎都可以正常工作(spring 是必需的,因此无法进行交换)

【问题讨论】:

    标签: spring maven spring-boot cucumber-java cucumber-junit


    【解决方案1】:

    这种问题可能会让您向最近的同事推出热咖啡。

    您是否看过这篇关于使用自定义 ResourceLoader https://github.com/cucumber/cucumber-jvm/issues/1320 的帖子

    我认为您必须复制并粘贴 Cucumber.java 类,将资源加载器从应用程序上下文提供给运行时,并将您的 RunnerCentral 类更改为 RunWith 新类。

    在我的例子中,我将原始项目放在一个 docker 容器中,它在启动时运行 ./mvnw test,这是 Spring Boot 项目中提供的 Maven Wrapper。如果使用公司存储库,您可以执行./mvnw test -s /path/to/maven/settings.xml,并且如果您的容器主机无法访问公司存储库,请首先在 Jenkins 框(或正在构建映像的任何位置)上运行映像,这将导致依赖 jar在里面下载,然后提交 docker 映像,然后将该映像推送出去。

    这样,容器可以使用其中的本地 .m2 目录运行黄瓜测试阶段,并且它需要的依赖项已经存在。

    【讨论】:

    • 谢谢,这是个好主意 - 会在时间允许的时候试一试,然后回来。
    • 最后评论 @RaduN - 我放弃了上述技巧,而是用普通的 Spring 依赖项(core/bean/context)和 maven-shade-plugin 替换了 Spring Boot 依赖项,它提供了可执行的 cucumber /弹簧罐。如果它只是你需要的 DI,它可能值得考虑..
    猜你喜欢
    • 1970-01-01
    • 2019-09-06
    • 2020-11-22
    • 1970-01-01
    • 2019-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多