[読書]テスト駆動開発
#test
#tdd
#dxd2021
読んだ本
モチベーション
- #dxd2021 の twadaさんのライブコーディング で日本語のテストメソッドをつくったりしていたのをみて、そういうポイントを理解してコーディングできるようにしたいと思った。
- 自分なりのテストフレームワークができて、次回以降はかならずテスト駆動で開発ができるようになることを目標にしたい。
- githubに草をはやしたい。
かかった時間など
- 期間 2021/4/15 〜 2021/5/13
- トータル時間 28 hくらい
- やりかた
- githubに写経用のリポジトリをつくって、動画確認しながら。
- 各項理解したことをREAME.mdにメモしながらなのでペースはゆっくりめ
書いてあることの要約
- テストを書かない場合の負のループ(ストレスが増えるとテストを書かない→バグが増える→ストレスが増える)を先にテストを書くスタイルで断ち切ることができるスタイル。つまりメンタルを安定させて開発をおこなうための方法である
- TDDのリズム
- まずはテストを1つ書く
- すべてのテストを走らせ、新しいテストの失敗を確認する
- 小さな変更を行う
- すべてのテストを走らせ、すべて成功することを確認する
- リファクタリングを行って重複を除去する
- 最初、さっさとテストを通すためなら、罪をおかしてもよい=ベタ書きのコードを書くなど。検討すべきことなどが浮かんだらTODOリストに追加する。リズムが大事
- レッドバーのパターン
- テストをはできるだけ小さく書く=大きなテストになって時間がかからないようにする
- Mock Object:本物につなぎ直してもつながるように擬似オブジェクトをつくってテストする
- Self Shut:オブジェクト同士の連携テストでは、テストオブジェクト自身をつかってテストするとやりやすい
- Log String:実行順序などログを出力させてチェックする
- Crash Test Dummy:エラーパターンは無理やり例外を発生させるようにしてテストする
- グリーンバーのパターン
- 仮実装
- 本実装
- 三角測量:似たような違うパターンのテストを入れて一般化する
- 明白な実装:単純な実装なら、一気に書いてもよい
- リファクタリングをする上で意識すべきデザインパターンがある。これは、有名なGoFのデザインパターンと重なる部分もあるし、TDD独自のパターンもある
- Command: 処理の実行をただのメッセージではなくオブジェクトとして表現する
- Value Object: 一度つくられたら絶対に値が変わらないオブジェクトをつくって別名参照問題を防ぐ
- Null Object: 特殊な状況をオブジェクトで表現する
- Template Method: 処理の順序を抽象メソッドのならびで表現し、個別の処理は継承によって表現する
- Pluggable Object: 2種類以上の実装をもつオブジェクトを呼び出すことでバリデーションを表現する
- Pluggable Selector: インスタンスごとに異なるメソッドを動的に呼び出すことで、余計なサブクラスを作らずに済ませる
- Factory Method: コンストラクタではなくメソッド呼び出しでオブジェクトを生成する
- Imposter: 既存プロトコルの新たな実装を作成して、バリエーションを生み出す
- Composite: オブジェクトたちの振る舞いの組み合わせを1つのオブジェクトとして表現する
- Collecting Parameter: さまざまなオブジェクトから処理結果を集めるためのオブジェクトを引数に渡していく
ざっくりと理解したこと
- テスト駆動開発の原点を学ぶ本だった。テスト駆動開発は、アジャイル開発などにも取り入れられてBDDのような形にもなったが、カオス状態になって幻滅期にはいったので、原点に立ち返って理解しなおそうという流れ1。
- 先にテストを通すコードを書いて、リファクタリングしたあともテストが通ってうれしい、というリズムが重要と理解した。
- 「先にテストを書く」こと自体も重要だが、それよりもそのあとのリファクタリングを早くかつ自信をもってやることができること がポイント。これにより、きれいなコードをつくりやすくなる。
感想
- テストを作ると本実装に加えて、そのテストのコードをメンテナンスする必要がでるので、メンテナンスコストなどをできるだけなくすプラクティスなどを求めていた。
- しかし、そういう意味ではパターンなどの記載はあったけど、そこよりもこの本ではテスト駆動開発のリズムのようなものを理解してもらうように書かれていた印象
- テストコードのメンテナンスコストを工夫するのは、別の機会でスタディする必要がある。
- ここでのユニットテストは開発のためのテスト(Developer Test)で、レグレッションテストとして保守されるべきなのは、まずはもう少しレイヤーの高いもの(System Test/Customer Test)なのかも
- これを学習後、テスト駆動開発で pycharmのリファクタリングチュートリアル をテストを追加してやってみたら、楽しかった。単純にpycharmの機能の復習ができて今後のリファクタリング速度があがる手応えが得られたし、その度にテストを流してちゃんとそのままの仕様が保証されて動いているのも確かめられた。
今後の展望など
- System Test/Customer Testの作成・メンテナンスの効率化について調査したい。ローコードテスト化の mabl というのが流行っているらしい。
- Pythonは、unittest / nose / pytest があるが、結局ベストプラクティス/デファクトスタンダードがどれなのか、よくわからないので、つかってみつつ調査を継続
-
付録Cでのtwadaさんの記述 ↩
最終更新日: August 24, 2022