Создание CI SOAP-сервисов на SoapUI + Maven + TeamCity
Коллеги, хочу поделиться опытом создания тестовой инфраструктуры.
Наша система построена на архитектуре SOA. Наружу торчат SOAP web-services. Наша задача состояла в том чтобы автоматизировать тесты сервисов, созданные в SoapUI, и включить в CI (TeamCity).
Начать решили с того, что спроектировали тесты, реализовали их в виде сценариев в SoapUI. Получилось порядка 100 позитивных и негативных тестов.
Следующим шагом было создание CI.
Подготовка окружения
JDK
Скачать и установить текущую версию JDK
Настроить переменную окружения JAVA_HOME, указать в качестве значения переменной каталог с установленным JDK, т.е. JAVA_HOME = <JDK_INSTALL_DIR>
Настроить переменную окружения PATH - добавить к ее содержимому путь к подкаталогу bin, в каталоге установки JDK, т.е. <JDK_INSTALL_DIR>/bin
Maven
Скачать текущую стабильную версию maven.
Распаковать содержимое дистрибутива в произвольный каталог (например, <USER_HOME>/maven)
Настроить переменную окружения M2_HOME, указать в качестве значения переменной, каталог с установленным maven (например, <USER_HOME>/maven)
Настроить переменную окружения PATH - добавить к ее содержимому путь к подкаталогу bin, в каталоге установки maven (например, <USER_HOME>/maven/bin)
Настроить переменную окружения MAVEN_OPTS, указать в качестве значения переменной -Xmx1024m (т.е. MAVEN_OPTS=-Xmx1024m)
Git
Скачать и установить текущую стабильную версию Git.
Установка и настройка проекта
Для установки проекта из Git-репозитория, необходимо иметь доступ к репозиторию.
Установка проекта (подразумевается, что все действия выполняются из командной строки):
Создать каталог git, который будет содержать репозиторий (например, <USER_HOME>/git).
Перейти в созданный каталог.
Для клонирования удаленного репозитория в локальный репозиторий, необходимо выполнить команду git clone ssh://git@git.name.ru/your-name.git
После завершения операции клонирования, в каталоге с git репозиториями, появится подкаталог your-name (например, <USER_HOME>/git/your-name)
Настройка локального профиля проекта:
В каталоге репозитория проекта <USER_HOME>/git/your-name/profiles, создать файл build-local.properties
В файле указать параметры:
soapui.ws.host = <WS_HOST> (Хост, на котором запущены тестируемые вебсервисы).
soapui.ws.port = <WS_PORT> (Порт, на котором запущены тестируемые вебсервисы).
Внимание!
Значения данных параметров будут подставлены в файл с описанием тестов <USER_HOME>/git/your-name/soapui-autotests/src/test/resources/auto-soapui-project.xml, вместо шаблонных значений: ${soapui.ws.host} и ${soapui.ws.port}
Запуск проекта
Для запуска проекта, наобходимо выполнить следующие шаги:
Перейти в каталог с проектом (<USER_HOME>/git/your-name)
Для запуска тестов, выполнить команду mvn clean test -Pdev -pl :soapui-autotests
После окончания выполнения тестов, в каталоге <USER_HOME>/git/your-name/soapui-autotests/target/soapui-logs будут созданы лог-файлы, в которых можно просмотреть результаты выполнения тестов.
Дополнительные файлы логов
В случае возникновения ошибок в тестах, для каждого ошибочного теста создается отдельный лог-файл в котором указаны подробности о возникшей ошибке, а так же request/response веб-сервиса.
Название таких лог-файлов, выводятся в основном лог-файле: <USER_HOME>/git/your-name/soapui-autotests/target/soapui-logs/soapui.log, например:
2015-05-15 17:53:00,508 INFO [SoapUITestCaseRunner] Running SoapUI testcase [OM-1019.заполнены только обязательные поля]
2015-05-15 17:53:00,508 INFO [SoapUITestCaseRunner] running step [createUpdate - Request 1]
2015-05-15 17:53:01,050 INFO [SoapUITestCaseRunner] Assertion [SOAP Response] has status VALID
2015-05-15 17:53:01,050 INFO [SoapUITestCaseRunner] Assertion [Script Assertion] has status FAILED
2015-05-15 17:53:01,050 ERROR [SoapUITestCaseRunner] ASSERTION FAILED -> assert holder["//errors"] == null
| | |
| | false
|
|
com.eviware.soapui.support.XmlHolder@46250430 (toString() threw java.lang.NullPointerException)
2015-05-15 17:53:01,050 ERROR [SoapUITestCaseRunner] createUpdate - Request 1 failed, exporting to [/home/mls/git/your-name/CanUpdate-OM1019заполнены_только_обязательные_поля-createUpdate__Request_1-0-FAILED.txt]
2015-05-15 17:53:01,056 INFO [SoapUITestCaseRunner] Finished running SoapUI testcase [OM-1019.заполнены только обязательные поля], time taken: 541ms, status: FAILED
В данном примере, ключевой фрагмент: /home/mls/git/your-name/CanUpdate-OM1019заполнены_только_обязательные_поля-createUpdate__Request_1-0-FAILED.txt, это и есть файл с подробным описанием ошибок теста.
Все лог-файлы c подробным описанием ошибки, так же создаются в каталоге <USER_HOME>/git/your-name/soapui-autotests/target/soapui-logs
Редактирование файла с описанием тестов SoapUI
В проекте можно обновлять файл с описанием тестов SoapUI.
Этот файл называется <USER_HOME>/git/your-name/soapui-autotests/src/test/resources/auto-soapui-project.xml
Что бы после изменения этого файла, изменения применились и в удаленном репозитории, нужно выполнить следующие шаги:
Перейти в каталог с проектом (<USER_HOME>/git/your-name)
Выполнить команду git commit -a
Убедиться, что в коммит попали изменения только в требуемом файле auto-soapui-project.xml
После запроса, ввести описание коммита (т.е. что было изменено в файле)
Выполнить команду git push master
ВАЖНО!
В фале с описанием тестов <USER_HOME>/git/your-name/soapui-autotests/src/test/resources/auto-soapui-project.xml, не указывать ХОСТ и ПОРТ веб-сервисов в явном виде! Использовать вместо них шаблонные значения: ${soapui.ws.host} и ${soapui.ws.port}
Например:
Вместо "…definition="http://111.22.0.66:8888/module-spu-mskgateway/ws/SpuGateway?wsdl"..."
использовать “…definition=“http://${soapui.ws.host}:${soapui.ws.port}/module-spu-mskgateway/ws/SpuGateway?wsdl”…”
Все
Пример POM файла с настрокой зависимостей.
<pluginRepositories>
<pluginRepository>
<id>smartbear-sweden-plugin-repository</id>
<url>http://www.soapui.org/repository/maven2/</url>
</pluginRepository>
</pluginRepositories>
<modules>
<module>soapui-autotests</module>
</modules>
<build>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*</include>
</includes>
</testResource>
</testResources>
<defaultGoal>install</defaultGoal>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>properties-validate</id>
<phase>process-test-resources</phase>
<goals>
<goal>testResources</goal>
</goals>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<id>properties-validate</id>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<quiet>false</quiet>
<files>
<file>../${mvn.properties.file}</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<source>1.7</source>
<target>1.7</target>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.0.6</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<properties>
<maven.build.timestamp.format>dd-MM-yyyy HH:mm</maven.build.timestamp.format>
<buildTime>${maven.build.timestamp}</buildTime>
<buildNumber>${build.number}</buildNumber>
<noDepsPattern>%regex[WEB-INF/lib/.*.jar]</noDepsPattern>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
Проблемы
В процессе создания нашей тестовой инфраструктуры мы получили ряд проблем
-
При прогоне тесты использовали одни и те же данные, указанные в переменных SoapUI.
Решение:
Стали хранить данные, необходимые для тестов, на стенде, где лежит билд агент. В скриптах SoapUI указано откуда брать данные и куда сохранять временные файлы. А так же ограничили запуск тестов только теми билд агентами, которые запускаются с того же стенда, где находятся данные тестов. -
TeamCity всегда показывает зелёный цвет, даже когда assertions некоторых тестов показали ошибки выполнения
Решение:
Пока не решили эту проблему, потому что не хочется останавливать выполнение всех сценариев, из-за ответа одного из тестов. После выполнения просматриваем ошибки вручную. -
Время на поддержку тестов никто не отменял
Профит
Думаю, польза от внедрения понятна - получили покрытие всех наших сценариев и прогон их за 10 минут в автоматическом режиме.
Дальнейшее развитие
Есть идеи добавить валидацию выполненных сценариев в БД, у SoapUI есть такая возможность, даже в бесплатной версии.