
みなさま、こんにちはあるいは、こんばんは。「プライベートは大事だよ」の、しろです。
以前「Playwrightはじめました」という記事を書かせていただきました。
その時は、画面操作して自動化できると記事を書きました。
が、今回は少し踏み込んだ内容で、Restful APIのテストについてご紹介したいと思います!
前提
この記事を読み進めるにあたり、以下の知識があるとスムーズです。
- JavaScript/TypeScriptの基本: 変数、関数、非同期処理(async/await)などの基本的な文法を理解している
- Playwrightの基礎知識: 先述の記事を参考に、Playwrightのインストールや基本的なテストの実行方法を把握している
- コマンドラインの基本操作: ターミナルやコマンドプロンプトでコマンドを実行できる
- Restful APIの知識:後述で触れますが、HTTPリクエストやJSONなどの知識があるとなおよし
Restful APIとは?
APIテストの話に入る前に、少しだけ「Restful API」について触れておきましょう。
そもそもAPIとは?
API (Application Programming Interface) は、ざっくり言うと「ソフトウェア同士が情報をやり取りするための窓口」のようなものです。例えば、天気予報アプリが気象庁のサーバーから最新の天気データを取得する際、この「窓口」であるAPIを介して情報のやり取りをしています。
RESTの考え方
REST (REpresentational State Transfer) は、そのAPIを設計する上での考え方・ルールの一つです。
ネットワーク上のリソース(情報やデータ)に、一意のURLでアクセスし、HTTPメソッド(GET、 POST、 PUT、 DELETEなど)を使って操作するという特徴があります。
以下のようにRESTの原則に従って作られたAPIを「RESTful API」と呼びます。
- GET: リソースを取得する(例: ユーザー情報を閲覧する)
- POST: 新しいリソースを作成する(例: 新しいユーザーを登録する)
- PUT/PATCH: 既存のリソースを更新する(例: ユーザー情報を編集する)
- DELETE: リソースを削除する(例: ユーザーを退会させる)
例えば
今回は株式会社アイビス様が提供しているzipcloudというAPIサービスを使用して、郵便番号から住所を検索できるサイトを使用してAPIを実行して、住所情報を取得していきます。
※ 過度なアクセスなどはお控えください。
例えば、東京駅の情報を取得します。
そのために「https://zipcloud.ibsnet.co.jp/api/search?zipcode=1000005」にアクセスします。
すると、以下のような情報を取得できます。
{
"message": null,
"results": [
{
"address1": "東京都",
"address2": "千代田区",
"address3": "丸の内",
"kana1": "トウキョウト",
"kana2": "チヨダク",
"kana3": "マルノウチ",
"prefcode": "13",
"zipcode": "1000005"
}
],
"status": 200
}
実践
それでは、実践いきましょう!
以降の記事の構成は、サンプルとして、実行できるプログラムコードを記載して、その後に各部分について解説していきます。
APIテストの概要
先述の通りですが、自前でAPIの構築や作成をするのは、少し手間がかかるので、zipcloudを使用して「東京駅」の情報を取得して内容を検証していきます。
本当は登録(POST)もしたいところですが、zipcloudにはデータを登録(POST)するための窓口は用意されていないため、今回は取得(GET)に絞って解説します。
#事前準備
Playwrightのプロジェクトが、まだない場合は、以下の記事を参考にセットアップをお願いします。
– 参考記事:「Playwrightはじめました」
サンプル
1. baseURLの設定
まず、playwright.config.ts
ファイルに、APIリクエストのベースとなるURLを設定します。これによって、テストコード内でURLの共通部分を省略できます。
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
// ... 他の設定
use: {
// APIリクエストのベースURL(共通部分)を設定する
baseURL: 'https://zipcloud.ibsnet.co.jp/api/search', // !!書き換える!!
trace: 'on-first-retry',
},
});
2. テストファイルの作成
次に、APIテスト用のファイルを作成します。ここではtc_get_zipcode_api.spec.ts
という名前にしました。
import { test, expect } from '@playwright/test';
test('郵便番号で住所を取得する', async ({ request }) => {
// 東京駅の住所を取得
const response= await request.get(`?zipcode=1000005`)
// レスポンスの検証
// ② レスポンスコードが「成功(2xx系)」であることの検証
expect(response.ok()).toBeTruthy();
// ③ レスポンスボディ(JSON)の検証
const json = await reponse.json()
// ③-1 結果が1件だけあること
expect(json.results).toHaveLength(1)
// 結果の1件目を取得
const result = json.results[0]
// ③-2 JSONの各項目の検証
expect(result.zipcode).toBe('1000005');
expect(result.prefcode).toBe('13');
expect(result.address1).toBe('東京都');
expect(result.address2).toBe('千代田区');
expect(result.address3).toBe('丸の内');
expect(result.kana1).toBe('トウキョウト');
expect(result.kana2).toBe('チヨダク');
expect(result.kana3).toBe('マルノウチ');
// ③-3 検証を緩和(具体的な値を検証しない)
expect(result).toHaveProperty('zipcode') // "zipcode"の項目が存在すること
expect(typeof result.zipcode).toBe('string') // "zipcode"が文字列型であること
})
解説
① 東京駅の情報をGET
まずは、データを取得する部分をE2Eテストと比較して見ていきましょう。
- E2E:page.goto({URL})
- API:request.get(`{EndPoint}`)
E2Eテストのブラウザページを操作するpage
オブジェクトを使いましたが、APIテストではリクエストを行うためにはrequest
オブジェクトを使います。
`request`オブジェクトのHTTPメソッド(.get()、.post()、.put()など)を呼び出してAPIリクエストを送信します。引数には、playwright.config.ts
で設定したbaseURL
に続くクエリを記載します。今回は?zipcode=1000005
です。
② レスポンスコードが「成功(2xx系)」であることの検証
まず、レスポンスコードとは・・・
HTTPリクエストにおけるサーバーからクライアントへのレスポンスを3桁の数字で表すものです。
200番台は成功レスポンス、400番台はエラーと定義されています。
本題ですが、以下のアサーションコードは、上記のレスポンスコードの検証をするためのコードです。
response.ok()は、HTTPステータスコードが200番台(成功)の場合にtrueを返します。これにより、リクエストが成功したことをまず確認します。
expect(response.ok()).toBeTruthy();
それ以外は、レスポンスコードを取得して、値として検証してあげる必要があります。
expect(response.status()).toBe(200);
③ レスポンスボディ(JSON)の検証
レスポンスのボディは、ただの文字列です。
なので、まずはawait response.json()
を行い、オブジェクトに変換(パース)して、中身を簡単に扱えるようにします。
おまじないの「await」を忘れずに!
変換したJSONオブジェクトの中身を検証します。
③-1 結果が1件だけあること
expect(json.results).toHaveLength(1)
JSONの中にある、results
という項目に、1件だけ(オブジェクト)値があるという検証をしています。
③-2 JSONの各項目の検証
expect(result.zipcode).toBe(‘1000005’);
これは、zipcodeにセットされている値が、「1000005」と一致しているか検証しています。
③-3 検証を緩和(具体的な値を検証しない)
expect(result).toHaveProperty(‘zipcode’) // “zipcode”の項目が存在すること
expect(typeof result.zipcode).toBe(‘string’) // “zipcode”が文字列型であること
上記は、コメントにも記載した通りなんですが、具体的な値を検証せずに、そもそも「zipcode」という項目があるかということと、「zipcode」にセットしている値が文字列型かどうかを検証しています。
あとがき
今回はPlaywrightを使ったAPIテストの第一歩として、GETリクエストの基本を紹介しました。クセがあるように見えたJSONのアサーションも、意外とシンプルに書けることがお分かりいただけたかと思います。
今後は、以下のような内容も追加していきたいと考えています。
- Pathパラメータやクエリパラメータの使用方法
- POSTリクエストとリクエストボディの送信
- ヘッダー情報の追加と検証
APIテストの世界は奥が深いですが、Playwrightを使えば一貫したツールでUIもAPIもテストできるのが大きな魅力ですね。
▼関連記事