🐕

単体テスト実装時の観点

2024/12/22に公開

概要

以下書籍を基に、単体テスト実装時の観点についてまとめました。

「単体テストの考え方/使い方」
著者:Vladimir Khorikov
訳:須田 智之
出版年:2022年
出版社:マイナビ出版
リンク:https://www.amazon.co.jp/単体テストの考え方-使い方-Vladimir-Khorikov/dp/4839981728

背景

単体テストのテストコードを実装する際、基本的にテスト対象のコードに沿って実装します。

テストコードを実装するファイルは、ビジネスロジック等を記載している箇所に依存するため、可能な限りテストコードを実装しやすいアーキテクチャで、プロダクション・コードを実装した方がよいです。

上記のような観点を持ってテストを作成する場合、アーキテクチャの修正をした方が良いと判断される可能性があります。

そのため、アーキテクチャに影響する可能性がある実装時の観点と、アーキテクチャに影響しないテスト観点を分けて記載しております。

単体テスト実装時の観点

観点

思想としては、「単体テストの考え方/使い方」に書いてある内容を基に書いています。

観点 Goodパターン Badパターン 理由
ControllerやConsoleのテストファイルにて、ビジネスロジックの観点の単体テストを書いていないかどうか。 HelperやTraitにビジネスロジックを記載し、単体テストではそのインスタンスorメソッドのレスポンスについてテストする。 複雑なビジネスロジックも、ControllerやConsoleのテストファイルに記載する。 Controllerでビジネスロジックをテストする場合、同じロジックを他のControllerで使うときに、同じ観点のテストを2つ以上作る必要があるため。
1つのテストメソッドの中で、複数の観点のテストを記載していないかどうか。 観点ごとに、テストを分割して実装する。
データプロバイダの利用を検討する。
Assertした後に、テストデータを作成して、再びAssertする。 単体テストが失敗した際、どの観点にてテストが失敗したかが、分かりにくくなるため。
ロジックを修正した際、どのテストコードを修正すればいいか分からなくなるため。
Mockを使わずに単体テストを実装できる場合でも、Mockを利用していないかどうか。 なるべくMockは利用しない。
外部メソッドを呼び出す場合のみMockを利用するようにする。
AssertDatabaseHas()メソッド等でテストできるにも関わらず、Mockを利用する。 Responseに影響のないリファクタリングを行った際、正しい挙動にもかかわらずテストが失敗する可能性があるため。
プライベート関数をテストしていないかどうか。 プライベート関数をテストしたい場合、プライベート関数を利用するpublicの関数をテストする。 プライベート関数をテストするために、アクセス修飾子を変更してテストする。 リファクタリングを行った際、正しい挙動にもかかわらずテストが失敗する可能性があるため。
テストコードのロジックに、プロダクション・コードのロジックを使用していないかどうか。 テストコードで、同じロジックを使う必要がある場合は、期待する返り値を定義して、ロジックを使わないようにする。 テストコード内で、プロダクションコードのロジックを使って値を作成する。 テストコード内で同じロジックを使ってテストした場合、通るのが当たり前のテストになってしまうため。
プロダクション・コードの中に、テストでのみ使用するメソッドが含まれていないかどうか。 インターフェースを使い、プロダクション用とテスト用でクラスを分ける。 プロダクション・コードの中に、テストでしか使わないメソッドを記載する。 障害が起こった際などでコードを見たときに、そのロジックがプロダクション・コードに影響しているかどうかわからないため。
「メソッドが呼び出されているかどうか」自体を観点にテストしていないかどうか。 Responseの値や、DBやファイルの値をテストする。
「メソッドが呼び出された結果どうなったか」という観点でテストを作る。
テストコード内で操作を行い、「メソッドが呼び出された」ことをテストする。 リファクタリングを行った際、正しい挙動にもかかわらずテストが失敗する可能性があるため。
テストコードが、AAAパターンとなっているかどうか。
参考:https://tech.pepabo.com/2021/08/23/writing-unit-test-with-aaa/
AAAパターンとなっていない場合、「データ作成→動作実行→結果や影響チェック」となるような順番で実装する。 Assertした後にデータ作成(Arrange)する。 上から下に向かってテストするため、可読性が落ちるため。

Discussion