用Cucumber测试Spring Boot应用程序

26

有人知道在哪里找到一个使用Cucumber和Gradle测试Spring Boot应用程序的示例应用程序吗?我可以在命令行上启动服务器并使用我的IDE运行测试,但我需要能够在CI服务器上以编程方式运行所有测试。我在这里看到了答案,但该解决方案对我没有起作用,很可能是因为我有多个步骤定义文件。

以下是我的设置

build.grade(在其他问题中提到)

testCompile ("org.springframework.boot:spring-boot-starter-test",
    ...
    "info.cukes:cucumber-spring:${cucumberVersion}")

CucumberTest.java

@RunWith(Cucumber.class)
@CucumberOptions(format = "pretty", features = "src/test/resources")
public class CucumberTest{
}

抽象的SpringTest.java(由所有StepDef文件扩展)

@SpringApplicationConfiguration(classes = Application.class)
@RunWith(SpringJUnit4ClassRunner.class)
@Ignore
public abstract class AbstractSpringTest
{ ... }

因为1. 尝试初始化我的步骤定义文件和2. 我的应用程序未启动,所以它在启动时没有执行正确的操作,导致cucumber测试无法建立连接。

谢谢。

编辑:或者如果有人可以告诉我如何使用gradle启动和停止应用程序,那也是可以接受的。


在您的Gradle配置中,在执行Cucumber测试用例之前启动Spring Boot。因为在执行Cucumber测试用例之前,您的Spring Boot应用程序应该处于运行状态。 - Manmay
我不太了解Groovy/Gradle,你能给我一个例子吗?它可以自动启动我的集成测试,所以我想我可以使用类似的机制。 - jakehschwartz
你尝试过使用 @IntegrationTest 吗?据我所知,这将启动你的 Web 服务器等。我还使用了 testCompile group: 'info.cukes', name: 'cucumber-junit', version:cucumberVersion,紧挨着 cucumber-spring。你能在 IDE 中将你的 Cucumber 测试作为 JUnit 测试运行吗? - Dude
是的,我已经包含了cucumber-junit。但我无法从IDE中将我的cucumber测试作为junit测试运行。在我的CucumberTest类中添加@IntegrationTest注释并将该类作为junit运行并没有解决我的问题。 - jakehschwartz
你是否尝试配置测试的上下文?@ContextConfiguration(classes = YourAppConfig.class, loader = SpringApplicationContextLoader.class)以及@IntegrationTest,你能否通过IDE运行你的应用程序,或者这也不起作用吗? - Dude
显示剩余2条评论
5个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
13

在这个问题的帮助下,我已经解决了问题:this question

以下是包含答案的存储库: https://github.com/jakehschwartz/spring-boot-cucumber-example

简而言之,AbstractSpringTest类需要具有以下注释:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = DemoApplication.class, loader = SpringApplicationContextLoader.class)
@WebAppConfiguration
@IntegrationTest

2
非常感谢! 我遗漏的一件重要事情是在类路径中存在info.cukes:cucumber-spring,没有注意到这一点,所以在尝试运行它时遇到了一些困难。 - Vova Rozhkov
2
从Spring Boot 1.2.1开始,您可以使用@WebIntegrationTest代替@WebAppConfiguration@IntegrationTest - Francesco
代码库无法工作。 运行 ./gradlew clean build 时测试失败。 - Martín Zaragoza
@MartínZaragoza 我不感到惊讶它不再起作用了,这个问题已经超过3年了。 - jakehschwartz

7

我有类似的症状,我的黄瓜无法启动Spring上下文...

后来发现我遗漏了以下依赖之一:

build.gradle

testCompile "info.cukes:cucumber-junit:1.2.4"
testCompile "info.cukes:cucumber-java:1.2.4"
testCompile "info.cukes:cucumber-spring:1.2.4"

StepDefs.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
        loader = SpringApplicationContextLoader.class,
        classes = Application.class
)
@WebIntegrationTest(randomPort = true)
public class StepDefs {

    @Value("${local.server.port}")
    int port;

}

Update: SpringBoot 1.5.1

@ContextConfiguration(
        loader = SpringBootContextLoader.class,
        classes = Application.class
)

我也遇到了同样的问题,而在其他网站上搜索到的唯一有效解决方法是安装SpringBoot 1.5.1的更新。 - Fernando Sanchiz

1
进一步回应@jakehschwartz,如果您希望Web应用程序在随机可用端口上启动,则AbstractSpringTest需要:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Application.class, loader = SpringApplicationContextLoader.class)
@WebIntegrationTest({"server.port=0"})
public abstract class AbstractSpringTest {

        @Value("${local.server.port}")
        protected int serverPort;
...}

0
我之前做过类似的事情来让Spring与JUnit参数化测试一起工作。虽然我还没有尝试过Cucumber,但它应该是相同的概念。我当时使用XML配置,所以这可能会有所不同。 < p >< strong > RunWithSpringJUnit4 < /strong >< /p>
public abstract class RunWithSpringJUnit4 {

    private TestContextManager testContextManager;

    public RunWithSpringJUnit4() {
        try {
            this.testContextManager = new TestContextManager(getClass());
            this.testContextManager.prepareTestInstance(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

黄瓜测试

@RunWith(Cucumber.class)
@CucumberOptions(format = "pretty", features = "src/test/resources")
public class CucumberTest extends RunWithSpringJUnit4 {
}

我不知道这是否会更好,因为这仍然无法启动我的应用程序。 - jakehschwartz
@JakeSchwartz 好的,这就是我要说的全部内容!祝你好运! - LucasP

0

首先,您需要确保在Gradle中已经应用了Spring Boot。调用gradle build将产生一个可运行的jar。不要让您的清单调用Spring类作为主要的入口,而是使用一个包装器将其启动在一个线程中,等待它稳定下来,然后运行Cucumber

@RunWith(Cucumber.class)
public class LucasePsCucumberTest implements Runnable {
    public static void main(String[] args) {
        Thread t = new Thread(this);
        t.start();
        // wait for t
        cucumber.api.cli.Main(null);
     }
}

那么您的意思是先构建jar包,运行jar包,然后在另一个线程中运行测试? - jakehschwartz
我想我明白你的意思,但我认为这对我没有帮助。我想我应该回去编辑我的原始问题。我没有问题运行黄瓜测试。我需要能够通过gradle运行它们,以便我的CI服务器可以通过我的构建。 - jakehschwartz
@hd1 你如何从静态方法中访问它? - deFreitas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,