25.8K Views
June 24, 23
スライド概要
CfPはこちら
https://fortee.jp/phpconfukuoka-2023/proposal/9af6e2bc-b64a-4287-baef-ee17ddd21560
セッションの動画はこちら
https://youtu.be/iqPsUaqjGGM?si=r-zyBVIi7biYHBxu
APIシナリオテストを書くべき 10の理由 PHPカンファレンス福岡2023 June 24, 2023(v0.0.4) Press Space for next page
自己紹介 katzumiと申します 「障害のない社会をつくる」をビジョンに掲げている「りたりこ」という会社に所属しています 以下のアカウントで活動しています katzchum k2tzumi katzumi
今日話す内容 本セッションの狙い APIシナリオテストとは? APIシナリオテストを導入したプロジェクト説明 APIシナリオテストを書くべき理由 まとめ
本セッションの狙い APIを実装する全てのエンジニアにAPIシナリオテストの便利さを知ってほしい SPAなシステムにE2Eテスト導入しようと考えている方にまずはAPIシナリオテストの導入をオススメした い
APIシナリオテストとは?
複数のAPIを連鎖的に呼び出し(Chaining Requests)て実行するテストのことです。
例えばユーザーの新規登録後に更新させるケースでレスポンス(ユーザーID)を次のAPIのパラメータとし
て引き継ぎながらAPIを呼び出すテスト。
1. ユーザー新規登録(Create User)
curl -X 'POST' \
'https://example.com/api/v3/user' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"username": "newUser",
"firstName": "John",
"lastName": "James",
"email": "[email protected]",
"password": "miserarenaiyo",
"phone": "12345"
}'
2. ユーザー更新(Update User)
curl -X 'PUT' \
'https://example.com/api/v3/user/{userId}' \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{
"username": "updatedUser",
"firstName": "David",
"lastName": "Smith",
"email": "[email protected]",
"password": "miserarenaiyo",
"phone": "12345"
}'
APIシナリオテストをクライアントに依存させずに実 行する方法 各言語のHTTPライブラリで実装 なんならcurlでも。。 APIテストにフォーカスしたツールは幾つかあります Postman (Newman) Karate Scenarigo
APIシナリオテストをクライアントに依存させずに実 行する方法 各言語のHTTPライブラリで実装 なんならcurlでも。。 APIテストにフォーカスしたツールは幾つかあります Postman (Newman) Karate Scenarigo One more…
katzchum @katzchum · Follow 推しツール は のシナリオテストツールです。yamlでOpenAPI ライクにサクッと書け、テストデータをdbやjsonフ ァイルから読み込めるなど、再利用性を高くテスト記述 できます。 バックエンド単体のE2Eテストをコード量少なく書けて 大変便利なので是非! runn API Spec tech.pepabo.com/2022/06/07/sce… k1LoW @k1LoW が loop: 構文を手に入れた上に json:// スキーム によるデータロードに対応したのでデータ・ドリブンテストや、なんな らGoのコードでTDTもできるようになったぞ!! @katzchum きっかけとなる提案から具体的な実装まで ありがとうござ いました! github.com/k1LoW/runn 11:09 PM · Aug 21, 2022 33 Reply Copy link Read 1 reply
APIシナリオテストを導入したプロジェクト説明 BaaSでREST APIのみ提供 パラメータが多くテストケース数も多い クリーンアーキテクチャで実装 単体テストはレイヤー毎にモックを使ってコントローラーテストまで実装 OpenAPIでスキーマ駆動開発 [1] APIはLaravel10で実装している QA組織がある プロジェクトの途中から runn を段階的に導入 1. 実装と乖離させないスキーマ駆動開発フロー / OpenAPI Laravel編 ↩︎
お断り OpenAPIでスキーマ定義されたAPIに対してrunnによるAPIシナリオテストを1年ぐらい書いてきた所感と なります。 runn固有の機能や特性についての記述は マークを付けています 使用ツールの具体的な使い方について説明は行いません。
APIシナリオテストを 書くべき10の理由
APIのスキーマの品質を向上させることができる APIのスキーマ(リクエストとレスポンス)に注目してテストできる ユースケースをカバーしてAPIのウォークスルーを行う インターフェースの欠陥を早く検知することができる OpenAPIのSpec通りになっているか?シナリオテストを書くだけでチェックできる
APIのスキーマの品質を向上させることができる APIのスキーマ(リクエストとレスポンス)に注目してテストできる ユースケースをカバーしてAPIのウォークスルーを行う インターフェースの欠陥を早く検知することができる OpenAPIのSpec通りになっているか?シナリオテストを書くだけでチェックできる desc: Test using HTTP runners: req: endpoint: ${TEST_HTTP_END_POINT:-https:example.com} openapi3: ../openapi3.yml steps: getusers: req: /users: get: body: null
APIのスキーマの品質を向上させることができる APIのスキーマ(リクエストとレスポンス)に注目してテストできる ユースケースをカバーしてAPIのウォークスルーを行う インターフェースの欠陥を早く検知することができる OpenAPIのSpec通りになっているか?シナリオテストを書くだけでチェックできる desc: Test using HTTP runners: req: endpoint: ${TEST_HTTP_END_POINT:-https:example.com} openapi3: ../openapi3.yml steps: getusers: req: /users: get: body: null
APIのスキーマの品質を向上させることができる APIのスキーマ(リクエストとレスポンス)に注目してテストできる ユースケースをカバーしてAPIのウォークスルーを行う インターフェースの欠陥を早く検知することができる OpenAPIのSpec通りになっているか?シナリオテストを書くだけでチェックできる desc: Test using HTTP runners: req: endpoint: ${TEST_HTTP_END_POINT:-https:example.com} openapi3: ../openapi3.yml steps: getusers: req: /users: get: body: null OpenAPIのSpecを指定しておくだけ
テストを迅速に開始できる 開発サイクルの非常に早い段階で結合テストを始めることができる APIの呼び出し元がまだなくてもテストを行うことができる → スキーマ駆動開発とすごく相性が良い
UIテストと比べて実行スピードが早い APIテストではレンダリング・入力待ちが不要でテスト実行時間が短くて済む UI Automation Vs API Automation - Quality Spectrum より To have a one to one comparison, we automated a test in our API suite and UI suite. The execution takes roughly around 7 minutes on the UI level, compared to just 12 seconds on the API level (that’s 35 times faster) 実行時間で35倍ぐらい差があるケースも 導入しているプロジェクトで266scenariosで5min41Sぐらい シナリオ内の総リクエスト数は1,183ぐらいで1Secで3つAPIを捌けるぐらい
テストの安定度が高い テストの安定度が高い=テストのメンテナンスコストが低くなる システム改修時におけるテストの影響度は、UIが最も高く、次にAPIスキーマ、最後にデータベースと なります Flaky Testになりづらい シナリオテストではデータの独立性を担保しやすい 各テストケースに異なる一意のデータを作成させて、テスト間の依存関係がなくテストの信頼性が高い
テストを効率的に書ける サーバーサイドの言語に依存せずにテストを書く ことができる yamlでOpenAPIのSpecライクに記述できる テスト観点が明確で記述量が少ないテストでレビ ューもし易い コントローラーテストをモックなしでテストを書 くのに比べても記述量が少なくて済む テストデータの準備もシナリオで定義し、見通し の良いテストとなる シナリオを共通化でき、データ駆動テストも可 更にシナリオ上で直接DBアクセス・操作も可能 steps: createUser: desc: Create User API ID req: /user: post: body: application/json: username: "alice" email: "[email protected]" test: steps.createUser.res.status == 200 updateUser: desc: Updated User API alice bob req: /user/{{ steps.createUser.res.body.id }}: put: body: application/json: username: "bob" test: steps.updateUser.res.status == 200 のテスト( が発行される) のテスト( を に変更する)
シナリオがドキュメント代わりになる 一連のユースケースがAPIチェーンで表現されるのでフローを理解し易い テストの記述量が少なくて読みやすい テストの安定度が高く、信頼度が高く読みやすいのでドキュメントとして相性が良い(ストックしやす い) API利用者からのAPIの挙動の問い合わせを受ける度にシナリオを作成していくと良い感じでストックされ ていく
自動テストへの組み込みが容易 CIに載せやすい SPAでフロントまで含めてE2E(ブラウザ)テストは大変だが、APIのみだったら難易度はそこまで高くな い 1バイナリなのでCIに組み込むのも楽。 Github Actionsも用意しています https://github.com/marketplace/actions/run-runn ここでもテストの安定度の高さが効いてくる
リグレッションテストにも使える CIで自動テストしているシナリオを微調整してリグレッションテストとして活用させる 環境変数で環境依存部分(エンドポイントやDB接続情報)の切替可、テスト用のステップをskipさせる 等が可能。 ゴールデンテストとの相性が良い リクエストとレスポンスの組合せが明確 Jsonファイルの読み込みをサポート(テンプレート機能あり)
ネガティブテストをしやすい リクエストの異常パラメータ(脆弱性を突くような)のパターンのテストを行いやすい → APIのクライアント側のValidationによって検証範囲が制限されることはない 冪等性確認する為に連続的にリクエストを行うテストもやりやすい loopを使って繰り返し実行させることが出来る
負荷テストにも活用できる シナリオを繰り返し実行すると負荷テストにもなる ロードテスト用の実行モードがあります デッドロックの検証も行えます シナリオなので実際のアクセスに近い形で検証ができる
まとめ
APIシナリオテストは時間を節約できる 結合テスト以降のサイクルを早めることができる システム・コンポーネント(フロントエンド含む)の結合前に最低限のテストが終わっている APIの仕様について早期フィードバックを得られやすい テストを書くことでセルフレビュー&ドキュメント化によるフィードバック 自動テストでユースケース〜シナリオテストをカバーできる 手動テストから解放され、複数の環境・ユースケースで安定性の高いテストが繰り返し可能となる。
APIシナリオテストはバランスが良くコスパが高い E2Eテストで効率よくカバレッジを上げることができる 実行時間・メンテナンスコスト・テストの信頼指標のバランスが良い Write tests. Not too many. Mostly integration. テキストベースで書きやすくシナリオを量産しやすい
テスト構成の比率を見直すと良さそう テスト戦略を見直してみましょう テスティングトロフィー(The Testing Trophy)とい 【テスト構成の見直し案】 う考え方 レイヤードアーキテクチャのレイヤー毎のテストを 補完させるのに良い ユニットテスト SPAのフロントエンドのAPI依存の部分のテストを 排除させる ブラウザテスト Kent C. Dodds @kentcdodds · Follow "The Testing Trophy" A general guide for the **return on investment** of the different forms of testing with regards to testing JavaScript applications. - End to end w/ @Cypress_io - Integration & Unit w/ @fbjest - Static w/ @flowtype 𝙁 and @geteslint ⬣ 3:53 AM · Feb 6, 2018 732 Reply Copy link Read 17 replies
参考URL runn https://github.com/k1LoW/runn APIシナリオテストの新ツールrunn https://zenn.dev/katzumi/articles/api-scenario-testing-with-runn runn クックブック https://zenn.dev/k1low/books/runn-cookbook runnによるAPIのシナリオテストの導入と自動化 / stac2022 https://speakerdeck.com/k1low/stac2022 Win Testing Trophy Easily / テスティングトロフィーを獲得する / PHPerKaigi 2023 https://speakerdeck.com/k1low/phperkaigi-2023
ご清聴ありがとうございます