はじめに
実務でテストの重要性を嫌というほど感じているので、読む。
自分用メモで気づきメインで書くので、
詳しく知りたい人は購入することを推奨。
こういう題材ってJavaとか多いよな。。
各章で、章の感想記事を読んだりして貼ることもある。
重複を除去する
1部 多国通貨
- 目標をTODOリストとして書き出す
- TODOリストから一つピックアップし、テストを書く
- テストコードを実行して失敗させる(レッド)
- 実装コードを書く
- できる限り最短でテストが通るコードを実装する(グリーン)
- コードの重複を除去する(リファクタリング)
- 次のTODOを選び、2に進む
第1章 仮実装
機能を作る時はTodoリストを準備する。
細かいステップを踏み続けられるようになることが重要、
第2章 明白な実装
仮実装→コードでまずベタ書きの値を使い、実装をすすめるに従って
徐々に変数に置き換えていく。
明白な実装 → すぐに頭の中の実装をコードに落とす
第3章 三角測量
ValueObject → その名のとおり値を表すオブジェクト。ここでいう値とはドメイン駆動設計という設計手法に登場する概念
|
|
同じインスタンスでテストが通ることもあるので、Trueを書いたらFalseも実装すると、テストとして担保される。
ただ、どうやってリファクタリングをするかわからない時などに使うべきなので、一時的に使用するといい感じ。
第4章 意図を語るテスト
値をそのまま比較するのではなく、オブジェクトどうしで比較してテストすることで、テストの意図を明確にできる。
値で比較しないことにより、amount
をprivateメソッドにできるのは参考になる。
第5章 原則をあえて破る時
・コピーアンドペーストによる再利用は、きれいな設計を壊すため抽象化の敗北になる。
素早く通るために、重複とかいろいろ罪は犯してよいが、これらは4,5のステップがあるからこそ意味のあるもので、
「設計をないがしろにしてよい」というわけではない
第6章 テスト不足に気づいたら
5章でコピーアンドペーストしたコードを綺麗にするために、2つのクラスの親クラスとしてMoneyクラスを導入し、
#equalsの実装を共通化した章。
テストが十分にない又は全くないコードに対してTDDを行うことも今後あるだろう。
十分な量のテストがない場合、テストによって守られていないコードのリファクタリングを行わざるをえない。
テストがないまま、リファクタリングを続けてしまうとコードを破壊してしまう。
テストがない場合は、リファクタリングのためにテストコードを書く。
第7章 疑念をテストに翻訳する
FrancとDollarを比較してみると、テストが通ってしまう。
頭の中の悩みをテストで表現した
完璧ではないものの、まずますなやり方(getClass)でテストを通した
さらなる設計は、本当に必要になるまで先延ばしにした
第8章 実装を隠す
DollarとFrancが似通っているので、Moneyクラスに処理を移譲。
テストの方は直接 Dollar や Franc のコンストラクタを呼んでいた部分が factory method に置き換わっただけ
この変更で直接 Money のサブクラスを呼ぶ必要がなくなり、これらを削除する準備が進んだ。
第9章 歩幅の調整
通過の概念(Currency)を導入して、サブクラスの実装をさらに近づけて行った章。
「気になって調べた割り込みに割り込みはしない」というルールは、
テストだけではなく全てに共通することだと思った。
第10章 テストに聞いてみる
デバッグのためにtoString
を書いて、テストを書かずに実装したのが印象的だった。
自身の実装がただしいかをテストに説いてリファクタする。
(少し曖昧)
第11章 不要になったら消す
サブクラスの仕事を減らし続け、とうとう消すところまでたどり着いた
サブクラス削除前の構造では意味があるものの、削除後は冗長になってしまうテストたちを消した
第12章 設計とメタファー
お金がお金自身を増やすようなことはなくて、お金を管理する第三者的なオブジェクトを登場させるほうが良くなりそう
という部分について触れられている章
第13章 実装を導くテスト
重複を除去できていないので、TODOリストの項目を「済」にしなかった
実装の着想を得るためにさらに先に進むことにした
後に必要になりそうなオブジェクト(Sum)の作成を促すテストを書いた
速やかに実装を行った(Sumのコンストラクタ)
キャストを使って以下書で実装した後で、テストが通るまで本来あるべき場所にコードを移した
ポリモーフィズムを使って明示的なクラスチェックを置き換えた
第14章 学習用テストと回帰テスト
必要になると予想されていたパラメータ追加をすぐに行った
コードとテストの間のデータの重複を括りだした
言語仕様を調べるテストを書いた
実装内部で使うためだけのヘルパークラスを個別のテスト無しで書いた
リファクタリング中にミスを犯したが、問題を再現するテストを追加して、着実に前進した
第15章 テスト任せとコンパイラ任せ
テストを書きたい時に
1.抽象度を落とし、具体的なテストを書きまくりまずは動作させた後にリファクタする方法
2.コンパイラを信頼し、自分がミスをしたら必ず教えてくれると信じて突き進む道
第16章 将来の読み手を考えたテスト
将来テストを読んだ人がメンテしやすいような書き方をすべき。
例えば、RSpecでいうと subject
や shared_example
を乱用しないなど、
共通化しすぎると読解に時間がかかるので、少し多く書いてもいいと個人的には思う
第17章 他国通貨の全体ふりかえり
プロセス
1.小さいテストを追加する
2.すべてのテストを動かし、失敗があることを確認する
3.変更を行う
4.再びすべてのテストを動かし、すべて成功すること確認する
5.リファクタリングを行い重複を除去する
テスト品質
テストコードは、システム開発し続けるためには有益
ただ、以下のテストの代替にはならない
・パフォーマンステスト
・負荷テスト
・ユーザビリティテスト
テスト評価手法
ステートメントカバレッジ
経路網羅率のこと
「全部の処理を1回は通るようにすること」が正 になるように設定して行うテスト(命令網羅で行うテスト)における「テストを全部やると、これだけ確認できるはずだよ。それに対して、今はこれだけの確認が終わってるよ」な割合のこと
欠陥挿入
「プロダクトコードの任意の行を変更したら、テストが失敗しなければならない」という考え方
感想
個人的には、クリティカルな部分は本当にちゃんとテスト書いてほしい。
そうしないと、リファクタがめちゃくちゃ難しく、その確認で工数がめっちゃ割かれる。
あと、Aの実装がBの実装に依存している時、AテストがB実装まで
面倒を見ないといけないようなテストコードは書かないでほしい
例) Service層とか
そういう場合はMockにするとか、AとBを分けてテストしたい。
テストしやすいコードにする必要があるので、設計はマジで大事。
第18章 xUnitに向かう小さな一歩
最初はDRYに書かずにベタ書きする。その後、リファクタする。
第19章 前準備
テストをシンプルに書けるほうが、パフォーマンスよりも大事だという意思決定をおこなった。
第20章 後片付け
テスト戦略をフラグからログに変更した
第21章 数え上げ
まずは仮実装を下記、ベタ書きの値を変数に置き換えることで段階的に実装を本物に近づけた
第22章 失敗の扱い
失敗するコードを書いてから、コードを書いてそれらを成功にしていく
第23章 スイートにまとめる
composite化をテストを通して行った
第24章
自分自身でxUnitを実装する意義。
xUnitの精神はシンプルさ
道具の中身を知るのは使いこなす上で重要
新しい言語でxUnitを実装してみると、その言語のある程度の機能は使えている
第25章 テスト駆動開発のパターン
ストレスレベルが増加した時におこること
「ストレスがかかるほどテストを行う頻度が減る。テストが減れば、テストが増える。
エラーが増えれば、ストレスも増える。以下同様に繰り返される」
テストをする前に、何をテストするのかをリストに書くこと。
実装から書くと、後からテスト書かなくなるので先にテストを書く。
エンジニア転職した時にやったほうがいいのは、
コードを読んで、仕様を自分なり外部(会社内)にアウトプットすることだと今更思った(今はNotionに結構書き始めてるけど、当時やってなかった)。
基本どこもドキュメント不足してる(予想)から有難がられるし、違ったら、
「あ~ここはAの経緯があって今はBでCなんだよ」
「実はこのコードは遺産で、、」
指摘が起こる。新規開発で仕様がよく変わるフェーズならしゃーなしやけど、やって損はないな。
コード理解も進むし、仕様もわかるし、有難がられるし、一石三鳥ヨシ!!!!
第26章 レッドバーのパターン
機能を書き始めるときの最初の問いは、「この機能はどこに属するべきだろうか」
第27章 テスティングのパターン
必ず小さくテストは始めること。
本物のデータベースは極力使わないこと
↓
これまじでやってる。反省
一人でコードを書いている時、コーディング時間のうまい終わらせ方は、テストを失敗する状態で
終わらせる状態
第28章 グリーンバーのパターン
仮実装の有効性
1.心理的効果 → グリーンとレッドでは精神状態が全く異なる。バーがグリーンなら、自分がどこにいるかわかる。そこから自信をもってリファクタリングを開始できる
2.スコープ制御 → プログラマは、この先起こる問題を予測するのが得意な生き物。1つの実例から始め
そこから一般化を行うことで、本質とは関係ない問題に気を取られずに作業を行えるようになる
仮実装の段階でテストを書くことは、デメリットよりメリットの方が大きいとのこと。
第29章 xUnitのパターン
共通コードを抽出するかどうかは、インターフェイスの変更の度合いを鑑みるとよさそう
第30章 デザインパターン
書くのがしんどいので割愛。ググったリンクを参考として貼る
https://github.com/at-grandpa/study-tdd/issues/36
第31章 リファクタリング
システムの設定変更を大きな変更であっても、小さなステップの積み重ねで行っていくパターン
TDDのリファクタリングは、テストさえ通れば、べた書きでもそれをリファクタリングという
考えつく限りのテストを書く
網羅性が大事
問題がありそうだったけど、他のテストが全部通ったのでコミットした、は許されない
リファクタは一つずつやることが正義
第32章 TDDを身につける
条件分岐
ループ
操作
ポリモーフィズム
がテストすべき対象
感想
確かに、プロジェクトが進む毎に変更が増え、testがないから
確認することが増え。。みたいなことは経験したことがある。
TDDほど、先にtestを書くことが必ずしも生とは言えないが、
testの向き合い方に関しては考え直すいい機会になった