Як можна тестувати вебсервіси за допомогою HTTP Client CLI, а також інших інструментів
Усім привіт, мене звати Віталій, і у цій статті я розгляну особливості тестування вебсервісів за допомогою HTTP Client CLI, а також коли підтримується взаємодія з WebSockets та gRPC сервісами. Детальніше прочитати про HTTP Client можна (після цієї статті) на сторінці продукту, саме CLI застосунку присвячена окрема сторінка.
Ця стаття в першу чергу націлена на програмістів, а не на тестерів. Хоча тестерам теж може бути цікаво, оскільки IntelliJ HTTP Client є альтернативою Postman, який, як я знаю, широко використовується в роботі наших колег зі сфери QA.
Крім всім відомих юніт-тестів є ще й інтеграційні (принаймі, я намагають використовувати їх у роботі). Для тестування клієнтів вебсервісів є зручна штука MockServer. А от для тестування самих вебсервісів ми зазвичай користувались старим добрим curl. Але всі ці опції... Та і запускати все це не зручно, треба зберігати запити десь у окремому файлі та копіювати.
Коли я розбирався з HTTP Client, знайшов альтернативи, такі як httpie та hurl, останній дуже схожий за ідеологією, раджу подитивитсь на нього також, особливо, якщо ви програмуєте не на Java. Ну, а тепер до справи.
Вступ
В квітні якось трохи випадково натрапив на вебпрезентацію Marco Behler The New HTTP Client CLI, у якій розповідалось про можливості використання HTTP Client у режимі командного рядка. Це відео можна подивитись прямо зараз. На додачу можно подивитись детальніше відео HTTP Client — Secret Weapon for Web Service Testing. Я не буду переповідати те, що розповіли у відео, перейду відразу до практичної частини, яка не потрапила у відео: використання клієнта у проєктах Maven та на платформах GitLab та GitHub.
З використанням наче все просто, якщо у вас встановлена IntelliJ IDEA чи споріднений продукт. АЄОА: якщо треба вбудувати тести у проєкт Maven чи використати їх у GitLab/GitHub/younameit: HTTP Client розповсюджується лише як бінарний застосунок, і підключити його в процес зборки можна лише як зовнішню програму, яку ще й треба попередньо скачати.
Почну з моменту про «скачати»: якщо ви користуєтесь ArchLinux, Manjaro чи іншими похідними, то в AUR доданий пакет intellij-http-client для встановлення ijhhp на комп’ютер, в якому навіть виправлена помилка з версією JDК. Для всіх інших є описані нижче варіанти, які також є у репозиторії на GitHub (кому зручніше на GitLab — там є копія). Ще є варіант з використанням Docker образу jetbrains/intellij-http-client, але я його не розглядав.
Maven
Перший підхід (для мене він був другим) спирається на плагіни download-maven-plugin та exec-maven-plugin. Додаємо у свій проєкт блок, тут я використовую Spring Boot, але, звісно, це може бути будь що.
Перед тестами скачується та розпаковується у target архів з ijhttp та запускається тестований код. Потім через exec запускаються тести, а після їх закінчення Spring Boot зупиняється.
<build>
<plugins>
<plugin>
<artifactId>download-maven-plugin</artifactId>
<configuration>
<followRedirects>true</followRedirects>
<outputDirectory>${project.build.directory}</outputDirectory>
<unpack>true</unpack>
<url> https://download-cdn.jetbrains.ком...intellij-http-client.zip
</url>
</configuration>
<executions>
<execution>
<goals>
<goal>wget</goal>
</goals>
<id>install-ijhttp</id>
<phase>pre-integration-test</phase>
</execution>
</executions>
<groupId>com.googlecode.maven-download-plugin</groupId>
<version>1.7.0</version>
</plugin>
<plugin>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jmxPort>9002</jmxPort>
</configuration>
<executions>
<execution>
<goals>
<goal>start</goal>
</goals>
<id>start</id>
<phase>pre-integration-test</phase>
</execution>
<execution>
<goals>
<goal>stop</goal>
</goals>
<id>stop</id>
<phase>post-integration-test</phase>
</execution>
</executions>
<groupId>org.springframework.boot</groupId>
<version>3.0.6</version>
</plugin>
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<arguments>
<argument>--report</argument>
<argument>your-test-requests.http</argument>
</arguments>
<executable>${project.build.directory}/ijhttp/ijhttp</executable>
</configuration>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
<id>http-test</id>
<phase>integration-test</phase>
</execution>
</executions>
<groupId>org.codehaus.mojo</groupId>
<version>3.1.0</version>
</plugin>
</plugins>
</build>
Другий підхід, з якого в мене все почалося, — це використання окремого плагіна. Коли дивився перше відео, у коментарях хтось спитав, чи є під це плагін. Я відразу перевірив і виявилось, що немає. Тож вирішив швидко написати.
Але плагін по суті є спрощеним варіантом exec, який вміє запускати лише HTTP Client. Тож не скажу, що він надає якісь великі переваги: трохи простіше і, можливо, зрозуміліше. Плагін не вміє скачувати HTTP Client, тому використання download-maven-plugin все ще потрібне. Може, згодом HTTP Client потрапить у Maven Central, і тоді плагін буде працювати сам собою без жодних додаткових «милиць».
Тут все так само: перед тестами скачуємо ijhttp до target, запускаємо Spring Boot, запускаємо тести і гасимо SpringBoot.
<build>
<plugins>
<plugin>
<artifactId>download-maven-plugin</artifactId>
<configuration>
<followRedirects>true</followRedirects>
<outputDirectory>${project.build.directory}</outputDirectory>
<unpack>true</unpack>
<url>
https://download-cdn.jetbrains.ком...intellij-http-client.zip
</url>
</configuration>
<executions>
<execution>
<goals>
<goal>wget</goal>
</goals>
<id>install-ijhttp</id>
<phase>pre-integration-test</phase>
</execution>
</executions>
<groupId>com.googlecode.maven-download-plugin</groupId>
<version>1.7.0</version>
</plugin>
<plugin>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jmxPort>9002</jmxPort>
</configuration>
<executions>
<execution>
<goals>
<goal>start</goal>
</goals>
<id>start</id>
<phase>pre-integration-test</phase>
</execution>
<execution>
<goals>
<goal>stop</goal>
</goals>
<id>stop</id>
<phase>post-integration-test</phase>
</execution>
</executions>
<groupId>org.springframework.boot</groupId>
<version>3.0.6</version>
</plugin>
<plugin>
<artifactId>ijhttp-maven-plugin</artifactId>
<configuration>
<executable>${project.build.directory}/ijhttp/ijhttp</executable>
<files>
<file>your-test-requests.http</file>
</files>
<report>true</report>
</configuration>
<executions>
<execution>
<goals>
<goal>run</goal>
</goals>
<id>http-test</id>
</execution>
</executions>
<groupId>uk.bot-by.maven-plugin</groupId>
<version>1.0.0</version>
</plugin>
</plugins>
</build>
На цьому можно було б завершити, адже це рішення працює будь де. Але, вже більше з цікавості, захотілось зробити «нативні» рішення для GitLab та GitHub.
GitLab
Почну з улюбленої платформи. Тут все дуже просто: додаємо таск, в якому скачується HTTP Client та запускається етап інтеграційних тестів. В проєкті Maven потрібні всі плагіни, крім download-maven-plugin, приклади наведені вище.
http-test: stage: test script: - microdnf install unzip - curl -f -s -L -o ijhttp.zip https://jb.gg/ijhttp/latest - unzip -nq ijhttp.zip -d target - unzip -nq ijhttp.zip -d target - rm ijhttp.zip - mvn $MAVEN_CLI_OPTS verify artifacts: reports: junit: - reports/report.xml
GitHub
У workflow так само додаємо кроки для скачування HTTP Client та запуску інтеграційних тестів.
❗️ До слова, забув сказати, що HTTP Client працює тільки з JDK 17 та вище.
steps: - uses: actions/checkout@v3 - name: Download ijhttp run: curl -f -s -L -o ijhttp.zip https://jb.gg/ijhttp/latest - name: Unpack ijhttp run: unzip -nq ijhttp.zip -d target - name: Remove ijhttp.zip run: rm ijhttp.zip - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' cache: maven - name: Build with Maven run: mvn verify
На завершення
Можливо, все що тут написано — це банальщина, але мені закортіло цим знанням поділитися.
Як казав на початку, я писав статтю з прицілом на девелоперів. На мою думку, HTTP Client може бути корисним або для швидкого тестування відомих кейсів, навіть якщо в команді є окремі тестери, або для тестування сервісу у випадку, якщо все тестування покладається на самих розробників, як це, наприклад, зроблено у Flix (проходив там нещодавно співбесіду).
Було б добре ще реалізувати підтримку HTTP Client у вигляді плагіна для Gradle, бо на останніх проєктах переважно використовувася він, а не Maven. Зроблю це, мабуть, трохи згодом.
7 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів