今回は「APIを叩いて検証するための“最小の自動テスト基盤”」を行っていきたいと思います。
目標は、VSCodeにおいて、JavaでAPIを最低限たたけるようにプロジェクトを作成すること。
補足Postmanとは
Web APIの設計・開発・テスト・管理をGUI(視覚的な操作画面)で行える世界的標準のAPI開発プラットフォーム。プログラムをわざわざ書かなくても、URLや送信データを入力するだけで手軽にAPIの動作確認ができることが最大の特徴。
※APIとかの説明は今回省略させてください。
Postman芸人って?
「Postman芸人」っていうのは正式なジャンル名じゃなくてネットのネタ表現なのであしからず。
Postmanを極めすぎてネタ化したエンジニア”って感じのスラングを指します。APIテストをPostmanで作り込みすぎるとかだといわれやすいのかな。
今回はPostman芸人にならないための記事を書いていこうと思います(戒めも込めて)
今回の環境構成
①VSCode使用
②Maven構成から作る
補足:今回のJavaの構成(ざっくり)
api-test/
├─ pom.xml(Maven設定)
└─ src/
└─ test/
└─ java/
└─ ApiTest.java(テストコード)
※「Maven設定ファイル」と「テストコード」は別物
■ STEP 1:Mavenプロジェクトを作る(VSCode)コマンドで作成
mvn archetype:generate -DgroupId=qa -DartifactId=api-test -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
このコマンドは「Javaのテスト用プロジェクトのひな形を自動生成する命令」となるもの。
ざっくりした意味は以下
「QA用のJavaプロジェクトを、いい感じのテンプレで自動生成して」
以下詳細
①「テンプレート(archetype)からプロジェクト作ってね」
mvn archetype:generate ...
②mvn
Mavenを使う⇒Javaのビルド・依存管理ツール
③archetype:generate
テンプレートからプロジェクト生成する機能
④-DgroupId=qa
Javaの世界での名前空間を作成
例:qa → テスト用プロジェクト
※今回は「QA用プロジェクト」という意味
⑤-DartifactId=api-test
プロジェクト名(フォルダ名)
⑥-DarchetypeArtifactId=maven-archetype-quickstart
「最小構成のJavaプロジェクト作って」という指定
中身は
・src/main/java
・src/test/java
・App.java(サンプル)
・pom.xml
⑦-DinteractiveMode=false
グループ名どうする?バージョンどうする?とかを聞かないで作ってねっていう指示
これで以下が生成されます。
api-test/
├─ pom.xml
└─ src/
├─ main/java/App.java
└─ test/java/AppTest.java
⑧VSCodeでプロジェクトを開く
ターミナルで以下を実行すると、プロジェクトが別ウィンドウで開く
cd api-test
code .
■ STEP 2:pom.xml の編集
今回追加するもの(RestAssured)
pom.xmlの に追加
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
以下、xmlのざっくり説明
①JavaでAPIを叩くためのライブラリ
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.4.0</version>
できること
HTTPリクエスト送る(GET/POSTなど)
レスポンス受け取る
JSONの中身を検証する
②junit-jupiter の意味⇒Javaのテスト実行フレームワーク
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
できること
テストを実行する
成功/失敗を判定する
テストをまとめて管理する
まとめ
| ライブラリ | 役割 |
|---|---|
| RestAssured | APIを叩く |
| JUnit | テストとして実行する |
③scope=test の意味⇒テストのときにだけ使う
本番アプリには入らない
テストコード専用
<scope>test</scope>
STEP 3:テストコードを書く場所
src/test/java/
① パッケージ作成
フォルダ qa を作ってその中に入れる指示
src/test/java/qa/ApiTest.java
補足■ AppTest.java を削除(サンプルで作られた古いテスト(JUnit3系)が邪魔してるとき)
src/test/java/qa/AppTest.java
STEP 4:Javaのコード書く
このコードの意味
外部APIを叩いて、返ってきた結果が正しいか自動でチェックするテスト
package qa;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class ApiTest {
@Test
void getUser() {
RestAssured.baseURI = "https://jsonplaceholder.typicode.com";
given()
.when()
.get("/users/1")
.then()
.statusCode(200)
.body("id", equalTo(1));
}
}
①package qa;
qaフォルダに入ってるクラスですよ、という宣言
インポートたち
②import io.restassured.RestAssured;
APIを叩くための本体(RestAssured)
③import org.junit.jupiter.api.Test;
「これはテストです」と宣言するためのJUnit
④import static io.restassured.RestAssured.*;
given()とかをそのまま使えるようにしてる(省略記法の書き方)
⑤import static org.hamcrest.Matchers.*;
equalTo()とかの「比較ルール」
クラス
①public class ApiTest {
テストのまとまり(テストケース集)
②@Test
このメソッドはテストとして実行する
テスト本体
①void getUser() {
テスト名。
②RestAssured.baseURI = "https://jsonplaceholder.typicode.com";
APIのベースURL(共通のURL設定)⇒毎回フルのURL書かなくてよくする
(/users/1だけでOKになる)
given()
given()
リクエストの準備
Postmanでいうと:Headers設定前、Body設定前
when()
.when()
実行フェーズ(PostmanのSendボタン押す瞬間を指す)
get()
.get("/users/1")
APIをたたく(実際にはURL全文をたたいているが、URL省略しているため"/users/1"でOK)
then()
.then()
結果の検証フェーズ
statusCode(200)
.statusCode(200)
HTTPステータス確認
200 = 正常
404 = なし
500 = サーバーエラー
Body検証
.body("id", equalTo(1));
レスポンスの中身チェック。
たとえば
{
"id": 1,
"name": "test"
}
■ ■ 全体の流れ
① URL設定
② リクエスト準備
③ GET送信
④ レスポンス受け取り
⑤ ステータス確認
⑥ JSON中身確認
補足:Postmanとの対応
| Postman | Javaコード |
|---|---|
| URL入力 | baseURI + get() |
| Sendボタン | when() |
| Status確認 | statusCode() |
| JSON確認 | body() |
これで、いったん
mvn testをターミナルで実行してエラー出なければOK
今回沼ったところ一覧
① Mavenコマンド実行場所ミス
src/test/java で実行してしまう
POMがないエラーなど
archetype生成失敗
② Mavenプロジェクトの階層理解不足
「フォルダの中にさらにプロジェクトを作る」発想になった
Springプロジェクトの中でさらに生成しようとした
not of packaging type 'pom'
module追加エラー
③ 同名プロジェクト再生成エラー
api-test を作った後にもう一度生成
Directory api-test already exists
④ PowerShellとcmdのコマンド混同
rmdir /s /q をPowerShellで実行
パラメータエラー
⑤ JUnit世代違い(レガシー混入)
Maven archetypeの古い AppTest.java が残る
JUnit3(junit.framework)が混ざる
TestCaseが存在しない
assertTrueが見つからない
⑥ dependency未解決(RestAssuredエラー)
io.restassured が見つからない
Maven依存の未取得
再読み込み不足
clean不足
⑦ Spring Bootプロジェクトとテストプロジェクト混在
Springアプリ(DemoApplication)をそのままビルド
QA用APIテストと同居
Spring依存が全部「存在しません」
⑧ 実行ディレクトリズレ問題
ターミナルのカレントディレクトリとプロジェクトルートのズレ
no POM in this directory
⑨ 初期テンプレコード放置
AppTestを消さずに実行
古いテストがビルドを壊す
まとめ
なんとかなったけど、普段使わないVSCode使うと沼る(大体が初歩的ミス)
次にやることメモ
テストの設計(正常/異常/境界)
APIテストの共通化
フレームワーク化
Postman完全代替