如何在 Eclipse 中使用 Gradle 运行 Cucumber + Spring Boot 应用程序

Posted

技术标签:

【中文标题】如何在 Eclipse 中使用 Gradle 运行 Cucumber + Spring Boot 应用程序【英文标题】:How to run cucumber + springboot application using Gradle in Eclipse 【发布时间】:2020-06-11 15:17:46 【问题描述】:

我有一个演示 springboot 应用程序并尝试使用 gradle 运行 cucumber 测试用例。在 maven 中它工作正常但无法使用 gradle 运行。 你能帮我从eclipse或命令行执行gradle文件的方法吗

下面是mt build.gradle文件

       testImplementation 'io.cucumber:cucumber-junit:5.3.0'
    testImplementation 'io.cucumber:cucumber-core:5.3.0'
    testImplementation 'io.cucumber:cucumber-spring:5.3.0'
    testImplementation 'io.cucumber:cucumber-java:5.3.0'
    testImplementation 'javax.xml.bind:jaxb-api:2.2.8'
    testImplementation 'org.mockito:mockito-core:1.9.5' 
    testImplementation 'junit:junit:4.12'
    testImplementation('org.springframework.boot:spring-boot-starter-test')
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    
    implementation ('org.springframework.boot:spring-boot-starter-actuator')
    exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    exclude group: 'org.springframework.boot', module: 'spring-boot-starter-log4j2'     
        
    

test
testLogging.showStandardStreams = true



sourceSets 
   main.java.srcDir "src/main/java"
   main.resources.srcDir "src/main/resources"
   test.java.srcDir "src/test/java/com/b**/f**/w**/tests"
   test.resources.srcDir "src/test/resources"


    configurations 
    cucumberRuntime 
        extendsFrom testImplementation
    




task cucumber() 

    dependsOn assemble, compileTestJava , testClasses

    doLast 

        javaexec 

            main = "cucumber.api.cli.Main"

            classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output

            args = ['--plugin', 'pretty', '--glue', 'com.b**.f**.w**.tests', 'src/test/resources']

        

    



下面是我在命令行中使用“Gradle cucumber”执行时的错误

> Task :cucumber FAILED
Feb 27, 2020 9:53:29 AM cucumber.api.cli.Main run
WARNING: You are using deprecated Main class. Please use io.cucumber.core.cli.Main
Feb 27, 2020 9:53:29 AM io.cucumber.core.cli.Main run
WARNING: By default Cucumber is running in --non-strict mode.
This default will change to --strict and --non-strict will be removed.
You can use --strict to suppress this warning
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/alekhya.machiraju/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-slf4j-impl/2.12.1/14973e22497adaf0196d481fb99c5dc2a0b58d41/log4j-slf4j-impl-2.12.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/alekhya.machiraju/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-log4j12/1.7.30/c21f55139d8141d2231214fb1feaf50a1edca95e/slf4j-log4j12-1.7.30.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/alekhya.machiraju/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.2.3/7c4f3c474fb2c041d8028740440937705ebb473a/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
Feb 27, 2020 9:53:30 AM io.cucumber.core.runtime.Runtime run
SEVERE: Exception while executing pickle
java.util.concurrent.ExecutionException: java.lang.NullPointerException
        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.util.concurrent.FutureTask.get(FutureTask.java:192)
        at io.cucumber.core.runtime.Runtime.run(Runtime.java:108)
        at io.cucumber.core.cli.Main.run(Main.java:75)
        at cucumber.api.cli.Main.run(Main.java:28)
        at cucumber.api.cli.Main.main(Main.java:15)
Caused by: java.lang.NullPointerException
        at io.cucumber.spring.SpringFactory.stop(SpringFactory.java:171)
        at io.cucumber.core.runner.Runner.disposeBackendWorlds(Runner.java:173)
        at io.cucumber.core.runner.Runner.runPickle(Runner.java:69)
        at io.cucumber.core.runtime.Runtime.lambda$run$2(Runtime.java:100)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at io.cucumber.core.runtime.Runtime$SameThreadExecutorService.execute(Runtime.java:243)
        at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
        at io.cucumber.core.runtime.Runtime.lambda$run$3(Runtime.java:100)
        at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
        at java.util.stream.SliceOps$1$1.accept(SliceOps.java:204)
        at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1359)
        at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
        at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:499)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:486)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
        at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
        at io.cucumber.core.runtime.Runtime.run(Runtime.java:101)
        ... 3 more

Feb 27, 2020 9:53:30 AM io.cucumber.core.runtime.Runtime run
SEVERE: Exception while executing pickle
java.util.concurrent.ExecutionException: java.lang.NullPointerException
        at java.util.concurrent.FutureTask.report(FutureTask.java:122)
        at java.util.concurrent.FutureTask.get(FutureTask.java:192)
        at io.cucumber.core.runtime.Runtime.run(Runtime.java:108)
        at io.cucumber.core.cli.Main.run(Main.java:75)
        at cucumber.api.cli.Main.run(Main.java:28)
        at cucumber.api.cli.Main.main(Main.java:15)
Caused by: java.lang.NullPointerException
        at io.cucumber.spring.SpringFactory.stop(SpringFactory.java:171)
        at io.cucumber.core.runner.Runner.disposeBackendWorlds(Runner.java:173)
        at io.cucumber.core.runner.Runner.runPickle(Runner.java:69)
        at io.cucumber.core.runtime.Runtime.lambda$run$2(Runtime.java:100)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at io.cucumber.core.runtime.Runtime$SameThreadExecutorService.execute(Runtime.java:243)
        at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
        at io.cucumber.core.runtime.Runtime.lambda$run$3(Runtime.java:100)
        at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
        at java.util.stream.SliceOps$1$1.accept(SliceOps.java:204)
        at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1359)
        at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
        at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:499)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:486)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
        at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
        at io.cucumber.core.runtime.Runtime.run(Runtime.java:101)
        ... 3 more

Exception in thread "main" io.cucumber.core.exception.CompositeCucumberException: There were 2 exceptions:
  java.lang.NullPointerException(null)
  java.lang.NullPointerException(null)
        at io.cucumber.core.runtime.Runtime.run(Runtime.java:120)
        at io.cucumber.core.cli.Main.run(Main.java:75)
        at cucumber.api.cli.Main.run(Main.java:28)
        at cucumber.api.cli.Main.main(Main.java:15)

FAILURE: Build failed with an exception.

* Where:
Build file 'C:\Users\alekhya.machiraju\eclipse-workspace\bProjet name\build.gradle' line: 133

* What went wrong:
Execution failed for task ':cucumber'.
> Process 'command 'C:\Program Files\Java\jdk1.8.0_241\bin\java.exe'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.2.1/userguide/command_line_interface.html#sec:command_line_warnings

我的文件夹结构如下

src/test/java

 ---- com.b**.f**.w**.tests
----------------Cucumberrunnertest.java
----------------Stepdefinition.java
src/test/reaources
----------------cucumber.feature

【问题讨论】:

可以试试黄瓜版v5.4.21吗? 【参考方案1】:

我遇到了与您类似的问题,但 Gradle 不会运行我的 Junit 5 + Cucumber 测试。看起来 Cucumber 没有任何 Junit 5 支持,所以我不得不恢复到 Junit 4(也称为 Junit 5 年份)。

我的诀窍是在我的build.gradle 中启用旧版 Junit 支持。

test 
  // Use old (Junit 4) runner since Cucumber doesn't support Junit 5 *sigh*
  useJUnit()
  // useJUnitPlatform()

我的代码/设置的重置:

build.gradle

plugins 
  id 'org.springframework.boot' version '2.2.1.RELEASE'
  id 'io.spring.dependency-management' version '1.0.8.RELEASE'
  id 'java'


group = 'se.snorbu.cucumber'
version = '0.0.1-SNAPSHOT'
configurations 
  compileOnly 
    extendsFrom annotationProcessor
  


repositories 
  // Use jcenter for resolving dependencies.
  // You can declare any Maven/Ivy/file repository here.
  jcenter()


dependencies 
  // Spring
  implementation 'org.springframework.boot:spring-boot-starter-web'
  implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

  // Cucumber
  testCompile 'io.cucumber:cucumber-java:6.6.0'
  testCompile 'io.cucumber:cucumber-junit:6.6.0'
  testCompile 'io.cucumber:cucumber-spring:6.6.0'
  testCompile 'io.cucumber:cucumber-junit-platform-engine:6.6.0'

  // Misc
  testCompileOnly 'org.projectlombok:lombok'
  testAnnotationProcessor 'org.projectlombok:lombok'

  // Junit5
  testImplementation('org.springframework.boot:spring-boot-starter-test') 
    exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
  


test 
  // Use old (Junit 4) runner since Cucumber doesn't support Junit 5 *sigh*
  useJUnit()

Cucumber-runner/-context

package com.example.webapp;

import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import io.cucumber.spring.CucumberContextConfiguration;
import org.junit.runner.RunWith;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;

@CucumberContextConfiguration
@RunWith(Cucumber.class)
@CucumberOptions(
        plugin = "pretty", "junit:build/cucumber-junit.xml", "html:build/cucumber.html",
        features = "classpath:/"
)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc
public class ContextConfiguration 


我的步骤定义

package com.example.webapp.steps;

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import io.cucumber.junit.platform.engine.Cucumber;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import se.snorbu.cucumber.webapp.PizzaClient;

import static org.hamcrest.core.Is.is;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@Slf4j
@Cucumber
public class OrderPizzaSteps 

    @Autowired
    private MockMvc mockMvc;

    private ResultActions mvcResult;

    @Given("A pizza")
    public void givenAPizza() 
       // Do setup
    

    @When("I order a pizza")
    public void whenOrderAPizza() throws Exception 
       // Do something
       
       mvcResult = mockMvc.perform(
                post("/order")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content("\"pizza\": \"pepperoni\"")
        );
    

    @Then("I should receive an order-id")
    public void thenShouldReceiveOrderid() throws Exception 
       // Do assertion

       mvcResult
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("id", is("A12")));
    

【讨论】:

以上是关于如何在 Eclipse 中使用 Gradle 运行 Cucumber + Spring Boot 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何使旧的 Eclipse 项目在带有 Gradle 的 Android Studio 上运行? [关闭]

如何让 gradle/Eclipse/play 框架协同工作?

Eclipse在运行或调试期间没有使用gradle依赖jar

如何在没有 Gradle 的 Eclipse 中的 Android 项目上启用 multidex

如何在 Eclipse 中使用 Gradle 和 ADT?

如何将spring导入到eclipse