はじめに
技術書クラウドファンディングのPEAKSから販売されているiOSテスト全書の第2章・ユニットテストを読んで、ユニットテストを導入する上で押さえておきたい点を備忘録としてまとめました。
ユニットテストとは
- ユニットテストとは、構造体やクラス、関数などのシステムにおける最小単位のコンポーネントに対して行うテストのこと
- 自動化され、繰り返し実行可能で、統一的な仕組みに支えられたテスト
- 上記を満たすために、テストを資産として残すことが可能で、テストの実行や結果のレポートを行ってくれるテスティングフレームワーク(XCTest、Quick/Nimble)を用いる
導入するモチベーション
1. より早い段階で不具合に気づく
処理単位で正しいことを検証できたら早いタイミングで不具合に気づくことができ、手戻りを減らせる
2. コードや設計を継続的に改善できる状態にする
ユニットテストの整備が安全網として働き、コードや設計を継続的に改善できる状態になる
例えば修正しづらいコア機能にユニットテストを整備することで修正しやすくなる
3. APIの利用方法をドキュメント化する
ユニットテストを記述することで対象のAPIの利用方法がわかる仕様書としての役割を果たす
実際に動くコードによってAPIの利用方法がわかるのはメリットとして大きい
特徴
- 高速かつ正確に実行できる
- 網羅的なテストが行いやすい
アサーション
- ある状態に対して、特定の操作を行い、その結果をアサーションで検証することがユニットテストの基本
- 状態:テスト対象のオブジェクトの状態や環境
- 操作:テスト対象の関数やメソッドを呼び出すこと
- 結果:関数の戻り値やオブジェクトの状態の変化など
- アサーション:期待通りの結果になっていることを検証する
保守性
1. テストのメソッド名
「test<テスト対象のメソッド名>_テストの説明」という規則で命名することが一般的
メソッド名にテストの説明を含めることでテスティングフレームワークがテストケース名として認識できる
2. 粒度
1つのテストでは1つの観点に対してのみテストすることが大切
3. 構造
色々な場所で利用するテスト対象(テストフィクスチャ)は一箇所で生成する
テスティングフレームワークのグルーピング機能を用いてテストを性質ごとにグルーピングする
4. エラーメッセージ
テストに失敗したときに原因の調査や修正にかかるコストを下げるために、エラーメッセージは失敗理由も添えて出力する
テストダブル
あるコンポーネントをテストしようとすると依存する別のコンポーネントまでテストしなければならない。テスト対象の依存するコンポーネントをテスト用に都合の良い振る舞いをする偽物に差し替えることでテスト対象を最小単位に留めることができる。このテクニックをテストダブルという。
テストダブルにはいくつかの役割があり、単体としての役割もあれば複数の役割を持ち合わせるテストダブルもある。
iOSアプリ開発のユニットテストにおいて利用頻度が高い役割は以下。
スタブ
依存コンポーネントのメソッドやプロパティにアクセスされた際に、テストに都合の良い値を返すように設定する
モック
依存コンポーネントのメソッドやプロパティへのアクセスについて、呼び出し回数や引数の値を記録し、記録した値が期待した通りか確認することで、テスト対象が依存コンポーネントと適切なコミュニケーションをしたかを検証できる