使用Spring Boot进行黄瓜集成测试

时间:2020-05-27 16:51:43

标签: java spring spring-boot maven cucumber

我一直在这里和其他站点上浏览无数帖子,无济于事。

作为CI管道的一部分,我正在尝试针对运行中的本地版本的Spring Boot应用程序运行我的黄瓜集成测试。我经常收到“拒绝连接”的提示,这会让您相信该应用程序无法启动,但是,如果我尝试使用测试在断点时提供的端口正常启动我的应用程序,它将告诉我端口已被使用。

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.busybee</groupId>
    <artifactId>backend</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>backend</name>
    <description>Busy Bees backend API</description>

    <properties>
        <java.version>1.8</java.version>
        <cucumber-version>1.2.5</cucumber-version>
        <unit-tests.skip>false</unit-tests.skip>
        <integration-tests.skip>false</integration-tests.skip>
    </properties>

    <profiles>
        <!-- The Configuration of the unit profile. This is the default profile -->
        <profile>
            <id>unit-test</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <build.profile.id>unit-test</build.profile.id>
                <skip.integration.tests>true</skip.integration.tests>
                <skip.unit.tests>false</skip.unit.tests>
            </properties>
        </profile>
        <!-- The Configuration of the integration-test profile -->
        <profile>
            <id>integration-test</id>
            <properties>
                <build.profile.id>integration-test</build.profile.id>
                <skip.integration.tests>false</skip.integration.tests>
                <skip.unit.tests>true</skip.unit.tests>
            </properties>
        </profile>
    </profiles>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>5.0.0</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java8</artifactId>
            <version>5.0.0</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>5.0.0</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-spring</artifactId>
            <version>5.0.0</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-all</artifactId>
            <version>1.3</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.197</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <!-- Run *Test.java tests as unit tests during test phase  -->
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.21.0</version>
                <configuration>
                    <skipTests>${skip.unit.tests}</skipTests>
                </configuration>
            </plugin>

            <!-- Run *IT.java tests as integration tests during verify phase -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.21.0</version>
                <configuration>
                    <skipTests>${skip.integration.tests}</skipTests>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>


</project>

BackendApplication

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
@EnableJpaRepositories
public class BackendApplication {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    public static void main(String[] args) {
        final SpringApplication springApplication =
                new SpringApplication(BackendApplication.class);
        // it is being added here for LOCAL run ONLY , spring profiles should be be run time parameters when run spring boot jar
        springApplication.setDefaultProperties(Collections.singletonMap("spring.profiles.default","LOCAL"));
        springApplication.addListeners(new ApplicationPidFileWriter());
        springApplication.run(args);
    }

}

步骤定义

public class GetNodeSteps extends CucumberBase {
    ResponseEntity<Location> responseLoc;

    @Before("@BeforeCreateLocation")
    public void create_existing_location() throws Throwable {
        Location location = generateLocation();

        responseLoc = template.postForEntity("/location/register", location, Location.class);
        if (responseLoc.getStatusCodeValue() == HttpStatus.BAD_REQUEST.value()) {
            fail("Couldn't create location");
        }
    } 
//Rest of steps omitted

CucumberBase

@SpringBootTest(classes = BackendApplication.class, webEnvironment = RANDOM_PORT)
@ContextConfiguration
public class CucumberBase {
    @Autowired
    public TestRestTemplate template;

    @LocalServerPort
    public int randomServerPort;

    @Before
    public void contextLoads() throws Exception {
    }

}

FeaturesIT

@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources/features", glue = {"com.busybee.backend.integration"})
public class FeaturesIT {
}

堆栈跟踪


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.4.RELEASE)

2020-05-27 17:49:49.787  INFO 20488 --- [           main] c.b.backend.integration.GetNodeSteps     : Starting GetNodeSteps on Rob-Desktop with PID 20488 (started by Robert in C:\dir)
2020-05-27 17:49:49.791  INFO 20488 --- [           main] c.b.backend.integration.GetNodeSteps     : The following profiles are active: test
2020-05-27 17:49:50.630  INFO 20488 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2020-05-27 17:49:50.694  INFO 20488 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 56ms. Found 4 JPA repository interfaces.
2020-05-27 17:49:51.183  INFO 20488 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-05-27 17:49:51.757  INFO 20488 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 0 (http)
2020-05-27 17:49:51.765  INFO 20488 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-05-27 17:49:51.766  INFO 20488 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.30]
2020-05-27 17:49:51.882  INFO 20488 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-05-27 17:49:51.882  INFO 20488 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2037 ms
2020-05-27 17:49:52.110  INFO 20488 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2020-05-27 17:49:52.184  INFO 20488 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.4.10.Final}
2020-05-27 17:49:52.323  INFO 20488 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
2020-05-27 17:49:52.449  INFO 20488 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2020-05-27 17:49:52.601  INFO 20488 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2020-05-27 17:49:52.626  INFO 20488 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2020-05-27 17:49:53.369  INFO 20488 --- [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2020-05-27 17:49:53.375  INFO 20488 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2020-05-27 17:49:53.967  WARN 20488 --- [           main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2020-05-27 17:49:54.199  INFO 20488 --- [           main] pertySourcedRequestMappingHandlerMapping : Mapped URL path [/v2/api-docs] onto method [springfox.documentation.swagger2.web.Swagger2Controller#getDocumentation(String, HttpServletRequest)]
2020-05-27 17:49:54.391  INFO 20488 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-05-27 17:49:54.439  INFO 20488 --- [           main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page template: index
2020-05-27 17:49:54.728  INFO 20488 --- [           main] d.s.w.p.DocumentationPluginsBootstrapper : Context refreshed
2020-05-27 17:49:54.749  INFO 20488 --- [           main] d.s.w.p.DocumentationPluginsBootstrapper : Found 1 custom documentation plugin(s)
2020-05-27 17:49:54.774  INFO 20488 --- [           main] s.d.s.w.s.ApiListingReferenceScanner     : Scanning for api listing references
2020-05-27 17:49:54.982  INFO 20488 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 58500 (http) with context path ''
2020-05-27 17:49:54.985  INFO 20488 --- [           main] c.b.backend.integration.GetNodeSteps     : Started GetNodeSteps in 5.609 seconds (JVM running for 6.852)

Step failed
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:58500/location/register": Connection refused: connect; nested exception is java.net.ConnectException: Connection refused: connect
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:751)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:677)
    at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:452)
    at org.springframework.boot.test.web.client.TestRestTemplate.postForEntity(TestRestTemplate.java:457)
    at com.busybee.backend.integration.GetNodeSteps.create_existing_location(GetNodeSteps.java:48)

感谢所有可以提供的帮助,谢谢。

1 个答案:

答案 0 :(得分:0)

我设法弄清楚了,我的H2数据库不是由SpringBootTestApplication创建的,因为我的测试属性是:

spring.jpa.hibernate.ddl-auto=update

何时需要:

spring.jpa.hibernate.ddl-auto=create