こんにちは!らーらです。
最近、お仕事でテストを書くことが多くなり、「そもそもテストとはなんぞや?」という疑問を解決するために、「初めての自動テスト ―Webシステムのための自動テスト基礎」こちらの本で自動テストについて勉強しました。
この記事では、自分への備忘録も兼ねて、
- テストを書く意味
- テストの種類
- テストを書くことのメリット・デメリット
について解説します。
フロントエンドエンジニアのようにテストに馴染みのない方や、これから自動テストを勉強していきたいという方が対象になっています!
テストを書く意味
「コードを書いて、意図したようにシステムが動けばいいじゃない!」
とテストを書いたことがないエンジニアは思います(わたしも思っていました笑)
しかし、1つの機能修正や機能追加が、他の機能に影響をあたえるような大規模なシステムの構築を行うと話は変わります。
Aという修正を行ったがために、今まで正常に動いていたBという機能が壊れる。
そして、大規模システムがゆえに、UIでの検証でバグが発見できず、リリース後ユーザーからの報告でバグが発覚。
大損害・・・
こういった事例は例を上げれば限りがありません。
そういった人間のチェックでは拾いきれないシステムエラーを自動で検出してくれるのが自動テストです。
テストの種類

基本的なwebシステムは上図のように、
- UI(ブラウザなどの見た目の部分)
- サービス(API などのサーバーと通信する部分)
- ロジック(サーバーサイドでの処理)
3つの階層に別れています。
どの階層までテストをするかで、UIテスト・統合テスト・ユニットテストに分けられています。
ユニットテスト

ユニットテストでは、システムの最下層のロジック部分だけを検証します。
ユニットテストは他の2つのテストに比べて、非常に粒度の小さいテストです。
例えば、引数で渡された2つの数字の足し算を行う簡単なメソッド(add(1, 5)のようなメソッド)がある場合、そのメソッドに対して
- 引数に2つの数字を与える
- そのメソッドからの返り値が、与えた2つの数字の合計値になっている
ということを保証するテストがユニットテストです。
上記のように、ユニットテストはロジックのメソッド単位でテストが記述できるため、非常に詳細に素早くテストを作ることができます。しかし、テストの対象が細かすぎるゆえに、統合部分(システム間の連携)における確認がしづらいというデメリットもあります。
ユニットテストの特徴
- ロジック部分を検証する
- メソッド単位で細かくテストが出来る
- 高速で動く
- 多目的に利用できる
- 統合部分の確認に弱い
統合テスト

統合テストは、ユニットテストから一回層上がって、サービスとロジックのつながりを検証します。
ざっくりまとめると、
- サーバーに対してリクエストする
- 正しいステータスでレスポンスが返ってくる
- レスポンスされた内容が正しい
を検証することが、統合テストです。
サーバーに対して、特定のリクエストを投げて、レスポンスされた内容が正しいかどうかを検証するので、様々なシステムが互いに正常に動作していることを確認することが出来ます。
しかし、レスポンスされた内容を検証するテストですので、「ロジックのどこが壊れていて、エラーになっているのか?」の特定が難しく、ユニットテストとの合わせ技が必要になります。
このようにHTTPリクエストとレスポンスを検証するテストですので、Web APIのチェックによく使われます。
統合テストの特徴
- システム間のつながりを検証する
- Web APIのテストによく使われる
- エラー時のバグの特定が難しい
UIテスト

最後のテストがUIテストです。
UIテストは、人間がチェックする時と同じ内容をテストします。
例えば、ログイン画面のテストを作成する場合、
- ログイン画面のURLをリクエストして、想定したページがレスポンスされる
- idのinputを入力する
- passwordのinputを入力する
- submitボタンを押す
- 認証に成功した場合、トップページにリダイレクトされる
といった、一連のフローをテストが自動で行ってくれます。
もし、上記のような想定した動きができなかった場合、テストはエラーを検出します。
つまり、UIの操作・サーバーへのレスポンスとリクエスト・サーバーでのロジック処理と、全てのレイヤーを通したテストを行うことができるのがUIテストです。
UIテストは、人間が操作を行う場合と同じレイヤーでテストが出来るため、汎用的(なんでも出来る)という大きなメリットがあります。一方、汎用的すぎて、もろく壊れやすいというデメリットもあります。
また、ユニットテストや統合テストに比べて、テストにかかる時間が圧倒的に多いということも事実です。それがゆえに、大規模システムのテスト構築時にUIテストを優先して作成してしまうと、テスト実行に何時間もかかってしまい、テスト自体行われなくなってしまうリスクもあります。
UIテストの特徴
- エンドツーエンドでテストする(ユーザー目線)
- テスト実行に時間がかかる
- 汎用的だが、もろく壊れやすい
テストのメリット・デメリット
テストの種類を解説してきましたので、今度は、テストを導入するメリットとデメリットをまとめます。
テスト導入のメリット
・安心して、機能追加・修正が出来る。
大規模システムを構築時に、1つの修正や機能追加が、既存の機能を壊していないかを自動で確認できる。
・思考の整理ができる
プログラム構築時にテストを書くことで、どういった場合にシステムがエラーを出すべきなのか?という視点からシステム構築が出来るため、思考の整理に役立ちます。
テスト導入のデメリット
・実装時間が増える
テストを書かずにシステム構築をするときに比べて、純粋にテストを書く分、時間がかかります。
・学習コストがかかる
プロジェクトに新メンバーが入る際、そのメンバーがテスト開発未経験だった場合、技術をキャッチアップするまでに学習コストがかかります。わたし自身も、テスト未経験から、テストゴリゴリのプロジェクトに参加したので、最初はとても戸惑いました笑
・なんちゃってテストになりやすい
しっかりとテストを理解して、テスト構築をしない限り、なんちゃってテストになる可能性が高いです。
テスト構築の基本
以上で、webシステムのテストに関する解説は終了です。
もしかしたら、UIテスト・統合テスト・ユニットテストと3種類のテストを紹介して、「結局、どのテストが一番いいの?」と疑問をいただいたもしれません。
結論としては、どのテストが一番優れているということはなく、メリットデメリットがあり、1つのテストに依存すること無く、3種類のテストを合わせて使うことで、テスト開発を効率的に進めていくことができます。
ただ、基本的には
- ユニットテスト
- 統合テスト
- UIテスト
と、下位レイヤーからテストを書いていくと破綻がなく高速なテストが書けると言われています。
ユニットテストで各機能のテストを行い、統合テストで機能ごとのつながりを検証する。その2つのテストでまかないきれない部分のみ、UIテストで検証する。
この流れがテスト開発の基本ですので、「どこからテストを書こう・・・」と迷った際には、この基本を思い出してください!
それでは、みなさん、よいテストライフを!!
以下の本を参考にテストを勉強しました。もっと詳しく、テストを勉強したい人は1読してみてください。サクッと読めるので、通勤中に読みやすいですよ!