単体テストの考え方/使い方
#読書 #テスト
輪読会: https://github.com/atman-inc/training/discussions
https://gyazo.com/d764fa21dcb351aef7e9e36209207608
はじめに
1
単体テストの作成に費やした労力が価値として最大限に引き出せる単体テストを作成できるようになることを目指す
1-1 なぜ、単体テストを行うのか?
良いテストと悪いテストの区別
網羅率(カバレッジ)
2
テストラスト開発
3
AAAパターン(Arrange-Act-Assert)
テスト対象システム(SUT)
テストダブル
テストスイート
jest > describe
テストのまとまり、コンテキスト
テストケース
jest > it
振る舞いや確認したいこと単位
テストスイート内に複数あってもよい
jest > expectは確認
一つのテストケースでのexpectは基本的に一つ
3.3
p70
テスト・ケースはプロダクション・コードが解決しようとしている物語(story)について語るべき
単体テストですべきこと
アプリケーションの振る舞いについて高いレベルで描画すること
プロダクションコードが何をするのかを単に列挙することではない
理想的なのは開発者だけでなく非開発者にも伝わること
フィクスチャの生成はコンストラクタよりもファクトリメソッド
4
CAP定理
テスト分析
テストピラミッド
ブラックボックステスト
ホワイトボックステスト
テストピラミッド
テスティングトロフィー
多くのプロジェクトはリファクタリング耐性を必要とするくらいの大きな規模になる前に開発が終わってしまう
5
CQS
副作用についての話
副作用起こすなら戻り値返すな
戻り値返すなら副作用起こすな
副作用は最初と最後に寄せる
なんかコネクティングドットしたkoushisa.icon
→TDD
外部から観測可能(public)な状態遷移をテストせよ
→Stateパターン
レイヤードアーキテクチャの話
きちんと設計されたテストケースはフラクタル構造である
テストケースを作成する際、どのようなビジネス要求があるのかがわかるようにしなくてはならない
テストにおけるロンドン学派と古典学派の違いは観測する時間軸の違いにありそう
依存関係の意味を区別する
6
リファクタリング耐性を決める要素
何もかもがモックに置き換えられた浅いテスト
モックが効果を発揮するのはアプリケーションの境界を超えて行われるコミュニケーションを検証し、かつ、そのコミュニケーションによって発生した副作用が外部からも確認できる場合
関数とはドメイン(入力)とレンジ(出力)の集合の関係のこと
関数型プログラミングではカプセル化は不要
7
HumbleObject
ドメインイベント(Domain Event )
副作用とドメインを切り離す
カプセル化したい重要なドメイン知識はドメインモデルに凝集させる
8
結合テスト
複数の実行フェーズを持つテストケースはE2Eに分類される
信号対ノイズ比(SN比)
9
モックを使うのはアプリケーション外部の境界に最も近い場所で管理下にない依存が行うコミュニケーションを検証する時だけにする
スパイは手書きのモック
外部境界に近いのであれば、モックよりもスパイの方が優れている
モックの利用は結合テストに限定する
モックに対して行われた呼び出しの回数を常に確認する
モックの対象になる型は自身のプロジェクトが所有する型のみにする
10
統合テストでは管理下にあるプロセス外依存をそのまま使うようにすべき
テストケースの異なるフェーズ(AAA)で同じトランザクショントランザクションを使いまわさない
あるテストケースのデータが他のケースに影響を及ぼしてはいけない
オブジェクトマザー
テストデータビルダー
読み込みに関してドメインモデルは必要ない
関連
t_wadaさんと「単体テストの使い方/考え方」の疑問点についてディスカッションしました - DeNA Testing Blog