Тестирование интеграции с клиентским серверным приложением в мультимодульном проекте Maven

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

Существует, например, модуль API, сервер и клиент.

Как клиент, так и сервер используют API в качестве зависимости, чтобы иметь возможность работать правильно. Клиент подключается к веб-службам сервера через HTTP при обычном использовании.

Чтобы функционировать, сервер должен запускаться на Jetty.

У меня есть модульное тестирование, которое работает и тестирует клиента, вызывая функциональность сервера с издеваемыми HTTP-запросами.

Я хотел бы иметь возможность провести некоторое интеграционное тестирование, чтобы проверить, например, соединение HTTP (и HTTPS) между двумя объектами, тестирование на тайм-ауты и т.д. и воспроизвести модульное тестирование, не прибегая к издеваемому запросу, ближе к реальным случаям использования.

Кажется, что такая вещь должна быть легкой, но я не могу найти способ сделать это просто и таким образом, чтобы это можно было автоматизировать.

Например, тестирование вручную в моей среде IDE выполняется путем нажатия "запустить войну" в проекте сервера и "запускать тесты" в моем приложении.

Есть ли способ воспроизвести этот простой процесс в Jenkins, так что это делается автоматически, с помощью конфигурации Maven или даже плагина Jenkins?

ОБНОВЛЕНИЕ:

Я пытаюсь сделать еще один модуль, который будет использовать войну в результате упаковки моего сервера и запустить ее с Jetty. Поскольку конфигурация сервера Jet Jet довольно сложная, используя конфигурацию Spring и https, отфильтрованную Maven, у меня есть некоторые проблемы, которые заставляют ее работать в моем новом модуле из-за отсутствия классов и относительных путей, не работающих в этом контексте.

Можно ли запустить эту войну, как если бы она была запущена в другом модуле, не перепрыгивая через обручи дублирующих ресурсов и другие грязные трюки?

Для информации, конкретная военная часть Jetty моего pom.xml:

<configuration>
                    <contextHandlers>
                        <contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
                            <war>${project.parent.basedir}/cmp-service/cmp-webapp/target/cmp-webapp-1.0-SNAPSHOT.war</war>
                            <contextPath>/cmp</contextPath>
                            <persistTempDirectory>true</persistTempDirectory>
                            <allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
                        </contextHandler>
                    </contextHandlers>
</configuration>

ОБНОВЛЕНИЕ 2:

Мне удалось создать функционирующий модуль, который запускает причал и запускает мой интеграционный тест с этим 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>parent</artifactId>
        <groupId>com.project.test</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.project.test.integration-testing</groupId>

    <artifactId>integration-testing</artifactId>
    <packaging>jar</packaging>

    <name>integration-testing</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.3.0.M2</version>
                <configuration>
                    <contextHandlers>
                        <contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
                            <war>
                                ${project.parent.basedir}/myserver/myservice/target/myservice-${project.parent.version}.war
                            </war>
                            <contextPath>/cmp</contextPath>
                            <persistTempDirectory>true</persistTempDirectory>
                            <allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
                        </contextHandler>
                    </contextHandlers>

                    <contextXml>
                        ${project.parent.basedir}/myserver/myservice/src/test/resources/jetty/jetty-context.xml
                    </contextXml>
                    <jettyXml>
                        ${project.parent.basedir}/myserver/myservice/src/test/resources/jetty/jetty.xml,${project.parent.basedir}/myserver/myservice/src/test/resources/jetty/jetty-ssl.xml,${project.parent.basedir}/myserver/myservice/src/test/resources/jetty/jetty-http.xml,${project.parent.basedir}/myserver/myservice/src/test/resources/jetty/jetty-https.xml
                    </jettyXml>
                    <systemProperties>
                        <systemProperty>
                            <name>scsf.configuration.file</name>
                            <value>
                                ${project.parent.basedir}/myserver/myservice/src/main/resources/config/cmpserver.properties
                            </value>
                        </systemProperty>
                        <systemProperty>
                            <name>org.eclipse.jetty.annotations.maxWait</name>
                            <value>180</value>
                        </systemProperty>
                    </systemProperties>
                    <systemPropertiesFile>
                        ${project.parent.basedir}/myserver/myservice/src/main/resources/config/cmpserver.properties
                    </systemPropertiesFile>
                    <daemon>true</daemon>

                    <stopKey>STOP</stopKey>
                    <stopPort>10001</stopPort>
                </configuration>
                <executions>
                    <execution>
                        <id>start-jetty</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>start</goal>
                        </goals>
                        <configuration>
                            <scanIntervalSeconds>0</scanIntervalSeconds>
                        </configuration>
                    </execution>
                    <execution>
                        <id>stop-jetty</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>stop</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.18.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
       ...
    </dependencies>
</project>

Вам также необходимо добавить зависимость к вашей войне.

Но (всегда есть), но есть проблема при выполнении цели проверки. Когда я запускаю проверку в своем модуле интеграции-тестирования, это работает. Но когда я запускаю цель проверки в родительском объекте, которая должна называть ту же самую цель проверки моего модуля интеграции-тестирования (если я правильно понимаю, как это работает), некоторые пути обрабатываются по-разному и разрешаются, например, parent/src/... вместо parent/integration-test/src...

Кажется, что при выполнении моей цели от родителя контекст выполнения изменяется и заставляет мое приложение ломаться при поиске ресурсов и т.д.

Есть ли что-то, что я не понял о том, как работает весь процесс, и есть ли способ заставить его работать?

ОБНОВЛЕНИЕ 3

Я решил взломать свой путь на пути всех путей к абсолютным путям, он работает, но он не объясняет этого поведения.

Ответ 1

Вы сами сами определили основные шаги:

  • создайте отдельный модуль для тестов интеграции
  • запустите приложение или веб-сервер (egjetty) с помощью соответствующего maven-плагина (например, cargo, wildfly-maven-plugin и т.д.) на этапе предварительной интеграции
  • выполнить тесты с помощью maven-failsafe-plugin:integration-test mojo
  • проверить результаты с помощью maven-failsafe-plugin:verify mojo

Стивен Коннолли, разработчик maven, уже написал отличный ответ по этому вопросу в stackoverflow.

Я не очень хорошо знаю jetty-maven-plugin, но, похоже, он не поддерживает развертывание существующего артефакта. Указание относительного или абсолютного пути окончательно не является способом перехода сюда. Вместо этого вы должны использовать груз, чтобы развернуть на причал. Конфигурация груза может выглядеть так:

<configuration>
  <configuration>
    <type>runtime</type>
    <properties>
      <cargo.hostname>testserver</cargo.hostname>
      <cargo.servlet.port>8080</cargo.servlet.port>
    </properties>
  </configuration>
  <container>
    <containerId>jetty9x</containerId>
  </container>
  <deployables>
    <deployable>
      <groupId>your.group.id</groupId>
      <artifactId>your-war</artifactId>
      <type>war</type>
      <properties>
        <context>/cmp</context>
      </properties>
    </deployable>
  </deployables>
  <deployer>
    <type>remote</type>
  </deployer>
</configuration>

Документация содержит более подробную информацию.

НТН,
- martin

Ответ 2

enter image description here

Привет, Джей,

Хотелось бы просто упростить ситуацию, почему бы вам не запустить эти задания подряд? Во-первых, это ваши компиляции, модульные тесты и развертывание задач с использованием Maven. Для тестирования интеграции создайте другое задание, которое будет использовать плагины, такие как Selenium (для вашего веб-приложения) и JMeter (для ваших веб-сервисов). Вы также можете попробовать другой набор для тестирования лицензий, такой как Openscript.

Тестирование веб-сервисов будет сложным, так как ваш пользователь веб-сервиса работает на другом клиенте. У вас есть ведомые агенты, запущенные в клиентском приложении? Если у вас есть, запустите эти задания внутри подчиненного устройства.