Maven Spring Boot Plugin: как запустить spring boot из другого проекта

https://docs.spring.io/spring-boot/docs/current/maven-plugin/usage.html

у меня есть проект, с 2 модулями.

[Parent]  
|-pom.xml
|  [SpringBoot2App]  
|  |-pom.xml  
|  [test]  
|  |-pom.xml  (start goal here!)

Я хочу запустить интеграционные тесты (Maven failsafe plugin) в отдельном проекте, который является другим модулем.

можно ли настроить плагин spring boot maven для запуска / остановки дочернего модуля во время интеграционных тестов родительского модуля?

Я пробовал что-то вроде этого без успех

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

            <configuration>

                <mainClass>com.SimpleServiceApplication</mainClass>
                <classesDirectory>../SpringBoot2App/target/classes</classesDirectory>
                <folders>
                     <param>../SpringBoot2App/target/test-classes</param>
                </folders>

            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>start</goal>
                    </goals>
                    <phase>pre-integration-test</phase>
                </execution>
            </executions>
        </plugin>

который не работает.

Я также попытался добавить параметр "project" после чтения источника супер класса плагина https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java

            <configuration> 
                <mainClass>com.SimpleServiceApplication</mainClass>
                <project>${project.parent.collectedProjects[0]}</project>
            </configuration>

Это относится к правильному проекту, как показывает debug, но не работает любой.

пожалуйста, не комментируйте [0], я знаю, что [0] не является чистым и является соединением, которое требует прямого знания порядка родительского модуля pom.

Я получаю java.ленг.NoClassDefFoundError на org/springframework/boot / SpringApplication

я добавил проект starter-web в тестовый pom.xml, тот же результат

2 ответов


Я не думаю, что можно запускать интеграционные тесты против другого модуля с помощью spring-boot-maven-plugin, потому что start цель, похоже, не дает вам средства для решения приложения из локального репозитория или реактора Maven, что, вероятно, то, что вы хотите. The project свойство конфигурации, которое вы пробовали, не предназначено для переопределения таким образом. Выполнение плагинов должно быть настроено с использованием только свойств, перечисленных в цели плагина docs.

Я думаю, что у вас есть по крайней мере два возможных подхода:
  1. использовать другой плагин для управления сервером; или
  2. запустите сервер непосредственно из тестов в коде.
1

для этого, я думаю, вам нужен подход, который копирует артефакт сервера, который вы хотите запустить, вместе с чем-то более общим для запуска и остановки его, например cargo-maven2-плагин или process-exec-maven-plugin.

только настройки repackage цель в сборке артефакта сервера:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <excludeDevtools>true</excludeDevtools>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

затем из модуля интеграционных тестов вы можете сделать что-то вроде:

<plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-server-artifact</id>
            <goals>
                <goal>copy</goal>
            </goals>
            <phase>pre-integration-test</phase>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>SpringBoot2App</artifactId>
                        <version>${project.version}</version>
                        <classifier>jar</classifier>
                        <outputDirectory>${project.build.directory}</outputDirectory>
                        <destFileName>app.jar</destFileName>
                    </artifactItem>
                </artifactItems>
            </configuration>
        </execution>
    </executions>
</plugin>

<plugin>
    <groupId>com.bazaarvoice.maven.plugins</groupId>
    <artifactId>process-exec-maven-plugin</artifactId>
    <version>0.7</version>
    <executions>
        <execution>
            <id>start-server</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>start</goal>
            </goals>
            <configuration>
                <name>run-server</name>
                <waitForInterrupt>false</waitForInterrupt>
                <healthcheckUrl>http://localhost:8080</healthcheckUrl>
                <arguments>
                    <argument>java</argument>
                    <argument>-jar</argument>
                    <argument>${project.build.directory}/app.jar</argument>
                </arguments>
            </configuration>
        </execution>

        <execution>
            <id>stop-server</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>stop-all</goal>
            </goals>
        </execution>
    </executions>
</plugin>
2

просто объявите обычную зависимость Maven от артефакта сервера из тестового артефакта и запустите@SpringBootApplication класс В JUnit перед крючком или что у вас есть, например

private static ConfigurableApplicationContext context;

@BeforeClass
public static void setUp() {
    context = new SpringApplicationBuilder(SimpleServiceApplication.class).run();
}

@AfterClass
public static void tearDown() {
    if (context != null) {
        context.close();
    }
}

этого может быть достаточно для ваших нужд.


решения от RyanP полностью соответствуют потребностям.

но, мне удалось заставить его работать, повезло, я думаю :)

  1. требуется повторное добавление зависимостей в тестовый модуль, которые необходимы для запуска приложения. (пружинный ботинок.starter-web в этом случае)

  2. добавление классов тестов, требуется очень интересный синтаксис

пока преимущества в том, что я могу запустить тест на работающем сервере, но все же макет нескольких сервисов с использованием профиля и тестовых классов сервиса.

честно говоря, я все равно попробую оба решения выше, но только для шоу, вот что я, наконец, получил работу

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

            <executions>
                <execution>
                    <id>start-mocked-app</id>
                    <configuration>

                        <arguments>
                            <argument>--server.port=${tomcat.http.port}</argument>
                        </arguments>

                        <mainClass>xxx.TestApplication</mainClass>
                        <classesDirectory>../${api-module}/target/classes</classesDirectory>

                        <folders>
                            <!-- wow! notice the weird "./" rather than the expected "../" -->
                            <folder>./${api-module}/target/test-classes</folder>
                        </folders>


                        <profiles>
                            <profile>MOCKED</profile>
                        </profiles>

                    </configuration>
                    <goals>
                        <goal>start</goal>
                    </goals>
                    <phase>pre-integration-test</phase>
                </execution>

                <execution>
                    <id>stop</id>

                    <goals>
                        <goal>stop</goal>
                    </goals>
                    <phase>post-integration-test</phase>
                </execution>
            </executions>
        </plugin>

и...

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