All Articles

Web API のテスト戦略

Web APIテスト技法を読んで、各テストアクティビティの定義などをまとめて理解をしておく。図などはこの書籍のものを使っている。

本書はMark Winteringham, "Testing Web APIs", Manning Publications 2022 の邦訳版。

テスト戦略

テストの目的は、テストアクティビティを通じて下記の円に何が含まれるかを最大限まで学ぶこと。 01 この円はプロダクトの振る舞いとその実装をカバーしているので、2 つの円のなかでテストをすればするほど多くのことが学べる。具体的には、品質に影響を及ぼすかもしれない潜在イシューの発見や楕円の組み合わせ部分を理解することでプロダクトの根本的な作りを理解しているという自信が学習によってもたらされる。

この円の内容をアプリケーション開発の具体的なテストアクティビティにマッピングされるとこのような配置になる。 02

API 設計テスト

アイデアに疑問を投げかけ、自分たちが解決しようとしている問題がなにかについての共通理解を築く。目的に対して 5W1H で問いをわけて考えると様々な角度からテストを考えられる。こちらのシートも参考になる。

探索テスト

Web API がどのように振る舞うかを学び、潜在イシューを見つけられるようにする。ただし、自由度や柔軟性があるため統制されたアプローチが必要である。それがなければ、個々人によるその場限りの探索で再現性のある成果が得られにくい。ではどういったアプローチが考えられるのか、まず大まかなアプローチ方法を紹介してその詳細をどう考えていくかを述べる。

大まかなアプローチとしては、以下のサイクルを繰り返すとしている。

  • 設計
  • 実装
  • 分析
  • 学習

学習した内容を元に設計を行い、再度探索を行うということを繰り返す。学習の結果をチームにフィードバックすることが求められる。そうすることでさらに探索する箇所の特定やチーム内でのシステムの理解が進む。

設計段階では、探索によってリスクを炙り出せるかどうかを定義する。
ex.)

Explore <Target>                <ターゲット>を探索する
Using <Tools>                   <ツール>を使って
To discover <Risk/Information>  <リスク/情報>を発見するために

どんなリスクがあるかという問いを立てたり、どんな探索が必要かという観点だしには以下のようなフレームワークが紹介されていた。

  • BINMEN

    • Boundary
    • Invalid entries
    • Null
    • Method
    • Empty
    • Negative
  • POISED

    • Parameter
    • Output
    • Interoperability
    • SEcurity
    • Exception
    • Data

探索テストでは多様な始点に基づく実行が可能なので、疲れてきたらやめることも推奨されていた。記録には obsidian のようなマインドマップ的なツールを使うといいかもしれない。これは自分で使ってみて改ためてフィードバックしてみたいと思う。

さらに詳しく学ぶために

コントラクトテスト

各チームの Web API が互いにやり取りでき、変更が起きたときに正しく更新されるようにする。Pact で運用するのがよいらしい。どんなことが検査できるかは アニメーション がわかりやすかった。これを見た理解としては、自分たちで管理している api を利用される側、利用する側の間の契約(コントラクト)を Pact が入り込んでくれるということ。Pact に api schema を渡しておくことで api 間で schema のミスマッチがないように運用できるようになると思われる。

パフォーマンステスト

負荷がかかったときの Web API のふるまいを理解するために役立つ。様々なアプローチがあり、何を学びたいかによってどのパフォーマンステストを実行すべきか決まる。

  • ロードテスト(負荷テスト)

    • ある水準や予想される水準のリクエストを行ったときにアプリケーションがどのように動作するか探る
  • ストレステスト

    • プロダクトを限界まで追い込んで限界がどこにあるか探る
  • ソークテスト

    • 長期間に渡って少量の負荷を与え続ける。メモリリークやサーバデータの許容量超過など時間をかけて発生するものをあぶり出す。
  • ベースラインテスト

    • ロードテストやストレステストと併用される。

テストは、KPI を定義して実施するテストのタイプと計測の対象を意識できるようにする。
ex.) 同時に XX 人の仮想ユーザーが YY のシナリオを行う
24時間 XX 人のユーザーが YY のシナリオを行っても平均 ZZ ms でレスポンスが返る

自動化された API チェック

API の動作についての自分たちの知識がまだ正しいかどうかを確かめるとともに、潜在的な品質低下への注意喚起の役割を果たす。品質低下の検出を行い、対応可否など判断は人間が行う。多くは起こってほしくない事象に対して検出を行いたいので対応がほとんどかと思う。
このフェーズでのテストとユニットテストできるものとの違いは、以下の観点で判断ができる。できるだけユニットテストに閉じ込めるのが望ましい。高速に検証可能なため。

A. API をテストする
B. API を介してテストする

A の具体例としては、API コールをしたときに Http Status Code が適当か判断したいケース。Bの具体例は、税額の計算結果を API をコールしてテストしているケース。後者の計算ロジックはユニットテストで検証できる。API の中にあるコードのインターフェースとして API を使っている。これはモジュールのレベルに寄せられるはず。なので、ユニットテストが望ましい。

雑感

モノリスであれば、コントラクトテストは基本的に不要かと思うので 自動化された API チェック = API 設計テスト X 探索テストの組み合わせになりそう。End to End の仕組みは作りやすいので CI でうまく回せそうなイメージはできる。API テストといえば End to End のイメージしかもっていなかったが、5 種類にも分けられるというの発見だった。区別ができることで、その手法によるトレードオフが考えられ、意思決定がしやすくなると思ったから。 パフォーマンステストにも種別があるのは知らなかったので、どれをまずは構築するかなど優先順位づけに役立つと思った。 負荷試験に取り組むことで自社の重要 KPI を意識せざるをえなくなるのはよいことで、製品としてどこの可用性を担保しないといけないか認識合わせにつながりそう。ここを意識できていると設計や実装も単純化、キャッシュなどを自然に考えられるようになるという副次的な効果も見込める。