take2 は https://github.com/haru01/log/blob/master/pattern_sheed.md
TDDを 初心者が熟練者になって、現場で実践していくコツを書いていきます。 すべて実施する必要はありません。上から順に実施する必要もありません。 現状の診断や、自分の状況に合いそうなものを複数ピックアップして、 ベイビーステップで個人やチームの学習と成長の物語を描く道具として使われることを想定しています。
まだ未完です。ガンガン変わっていきます。 :p
目標 25個、 50個 練習場編、現場実践編、不吉な匂いの3本立て。
TDDを開発の現場に持ち込みたいと考えている人。持ち込んで継続したいと考えている人。継続して広げていきたいと考えている人。 読者の現場によって、選ぶパタンは異なる。
ここで指すTDDは、XPの意図を汲み取って、BDD、GOOSと同様に、Acceptance Testも 範囲内としてTDDを語る。ただし、エンドユーザの実際の使用からの学習フィードバックループを 取り込む活動については、予感のみにとどめTDDの範囲外として語る。
Acceptance TestもTDDの範囲内とするが、導入ステップを、アウトサイド・イン、 インサイド・アウトどちらで攻めるかのオススメは保留し、現場の判断とする。
あとで書く
私は、テストの書き方を練習しようとしています。 が、私は、今まで、テスティングフレームワーク,CIを触ったことがありません。
ツールなしには、私はテストを書くこと、実行すること、実行結果を見ることはできません。 テストハーネスなしにTDDを始めることはできないでしょう。
それゆえ
試しに自分のマシンにテストの実行環境を用意しよう。
環境があれば、実際に手で触って試して学ぶことができます。
私は、普段、Red Green Refactor のサイクルでプログラミングをプログラミングしていません。 いつもは、デバッカー、println、外側から【目視】で動作確認しています。
Red Green Refactorのリズムを己の肉体で魂で実体験したことがなく、一体何がおきているかさっぱりわかりません。
それゆえ
とてもとても簡単なお題を Red Green Refactor のリズムで、解いてみよう。
実際に体を動かして試して心で感じることが、TDDを理解し始める一歩となります。
Red-Green-Refactorのリズムが馴染めず、私の体と心がTDDの拒絶反応を示している。 どうしても、Red Green Refactorが慣れないのであれば、 Red Green Refactorの制約を緩める。 ちょっと実装して、ちょっとテストを書いて、リファクタリングするを繰り返すですすめる。 ある程度進めたところで、既に書いたてテストを参考に、先にテストを書くを試みてみる。
別名: 量は質に転化する。練習、練習、練習。写経
私は、まだTDDを勉強し始めたばかりで、Red Green Refactorのリズムがまだ、体と頭に染み付いていません。
実プロジェクトではじめようにも、なかなか思うようにTDDでプログラミングができず、もどかしい思いをしています。 うまくテストから書き出すことができないので、実装からはじめて、テストのこと忘れてしまいます。
[Kode Kataの説明、練習の重要性の説明を 引用ベースで]
それゆえ 安心して失敗して学ぶことが出来る練習時間を用意しよう。簡単なお題をTDDで何度も何度も解いてみよう。
何度も繰り返すことで、Red Green Refactorのリズムが体と心が馴染みます。 繰り返すことで、だんだんとTDDのリズムが刻めるようになります。各々のテスティングフレームワークやテスト用のライブラリーも語彙・イディオムに癖があります。練習しておくと頭が指がスムーズに動くようになります。 練習は、本番とは異なり安心して失敗できる場です。はじめは躓く事が多いでしょうが、そこから学びがあるはずです。
TDDのWebの動画、ペアプロ、TDDBCなどの機会を通じて経験者のTDDの進め方を目で見て、真似てみる。
私は、1人でTDDを学ぶことに心細さを感じています。
個人の独学だけでは、限界があります。身の回りにもTDDを実践している人がおらず質問する人がいません。
それゆえ
TDDBCもしくはそれ相当のハンズオンセミナーに参加しよう。
TDDBCに参加できれば、経験者による実際のRed Green Refactorの動きを見ることができ、 疑問感じていることを質問して解消することができます。
また、経験者のTDD過程を実際に自分の目の前で見ることで新しい発見が期待できます。 初めてTDDを目撃する人にとっては、Red Green Refactorのサイクルの短さに何かしら驚きと発見を見出すようです。 真似て学ぶことができます。
リファクタリングで、動作する「汚いコード」から「きれいなコード」変換せよというけれど、私は、何が汚いか綺麗かの判別できません。
動作するきれいなコードの「きれいなコード」ってなんだ?
それゆえ
一旦TDDは脇に置いて、不吉な匂い、言語のイディオム、パターン、設計原理について学ぼう。不吉な匂い、イディオム、パターン、設計原理を使ってコードについて語り合おう Greenの際に、どこをリファクタリングすればよいかわかります。良い名前付けができるようになります。 テストで使用例のサンプルコードを記述する際よりベターのAPI設計ができるようになります。
not 工程単位
時間外で、テスト環境準備、テストを書き出し
新しい取り組みを始める際は、Why(なぜ必要?効果は?)を周囲から問われることがあります。
TDDのメリットをコードから距離のあるビジネス側やマネージャの人を説得するのは難しいです。 今の段階は、許可を求めず謝罪せよが良さそうな予感がします。
それゆえ
特に周りを説得せずに、ひっそり始めましょう。 TDDは一人でも始めることができるプラクティスです。特に肩肘はらず「TDDをやっている」などとは言わず、 「プログラミングしている」と言いましょう。 上司への説得コストは下げて、現場で開始することができます。
私は、新しい取り組みを始めるにも、スケジュールがきつく「時間がない」と感じています。 チームで、「ワークキューの流量制限」「時間泥棒の逮捕」「プログラミングの完了条件の明確化」 の実施で時間を確保することが難しいと感じています。
新しいことを学ぶことに時間がかかります。プロジェクトが多忙です。 フルタイムでTDDを実施しながらタスクを完了させることにハードールが高いと感じています。
それゆえ
私が出来る範囲内にTDDの実施を限定しましょう。タイムボックスを決めて、小さくトライしましょう。 例えば、多忙プロジェクトでも週に4hだけTDDにトライアルすると決めて、実施しましょう。 多忙の中でも、実プロダクトでTDDを小さくトライすることで、練習では得られない現場での学びが得られます。
不規則な「割り込み」と呼ばれる現象と呼ばれる現象が、「時間がない」を引き起こし、 「テストを書かない」に陥ることも 個人レベルで「割り込み」と呼ばれる現象にどのように対処していくか。 「一人を犠牲に」や、スクラムのような「見積りと計画づくり」が使えない。 割り込みタスクを入れ替えた際の、影響範囲をキチンと説明し、優先順位の話、期限に間に合わない話などをキチンとしてから仕事にとりかかる。
選んだテスティングフレーワーク、チェックスタイル、ビルド依存、実行までのロード、マシン、環境などによって、 短いサイクルで、Red Green Refactor ができずTDDの阻害要因となっている場合がある。
テストハーネスは準備しました。既存システムで今は1行もテストコードはありません。 私は、今、どっからTDDに取り組めば良いか途方にくれています。
それゆえ バグ再現と対処などTDDできる対象を見つけましょう。 1つでもテストが記述できれば、そこを参考にテストを成長させることができます。
現場のプロダクトにTDDを始める候補が幾つかありますので参考にしてください。
障害の再現テストを記述して直すをTDDでやってみる作戦。
新機能の実装の際に、TDD出来そうなところを探す作戦。
既存コードにテストを補強してから、TDDを開始する作戦。
既存コードにテストを補強してから、TDDを開始する作戦。 レイヤの観点からではなく、ビジネス上の重要資産の観点で対象を見つける。
歯を食いしばって、テストの差し込み、テストしやすい設計に変えていく。
説得コストの低いフォローワーを見つける。1人よりも活動を継続しやすい。
バグ報告件数や手動テスト時間を測定し、次のアクションの判断材料にする。
ビジネス側やマネージャの関心ごとは、コードの質やテストの自動化よりも、 動くものが早くこの目で確認したいと感じています。直接TDDの嬉しさを伝えづらいと私は感じています。
TDDのメリットをコードから距離のあるマネージャの人を説得するのは難しいです。 だからといって「1人でひっそり」ではなくビジネスサイド・マネージャを巻き込んで活動を取り組んでいきたいです。
それゆえ
TDDは一旦脇に置いといて、1日以下サイクルで頻繁なデモから始めましょう。 デモ環境を通じて、ビジネス側・マネージャと開発者がつくっているものについて頻繁に会話してフィードバックできる、 信頼関係を醸成できる環境を用意しましょう。信頼関係を醸成できれば、TDD導入の理解が得られやすくなります。
テストハーネスの準備、テスト対象の選定、テストの書き方などを自力で解決するのは難しい。 指導者によって、指導者が、複数のプロジェクトを巡回して、自動テストの対象の選定、テストハーネスの入れ方、テストの書き方などのコツを伝える。 指導者がいなければ、外部コーチを雇う。その役割を持った人を育てる。
ついつい、今までのお仕事の進め方に戻りがち。定着するまで口酸っぱく言い続ける人がいると良い。 ロールモデルは、Clean Coder の2章、3章のような発言をする人。スクラムマスターの完了マスターのような人
ついついマシンとの対話に熱中し、人との対話を怠ると、良質なテストパターン、動作するきれいなコード、よい設計に辿りつけない。
前述
通常、開発プロジェクトは多忙のことが多い。私は、日ごろの仕事の多忙に圧倒されています。
TDDなど新しいことを始めるよく出会う最大の敵は「時間がない」です。
それゆえ
新しく始める前に、不要な活動を削除し時間を確保することに注力しよう。
代表的な時間泥棒の逮捕は次で行われる。
不要なフィーチャの削除: つくる理由Whyを確認しよう。誰向けなのか? なぜそれが必要か? それがないと何に困るのか? あると何が嬉しいのか?を確認しよう。
まともな理由が語られないのであれば、それは、価値を産まない無駄なフィーチャの可能性があります。削除、簡略化できないか提案しましょう。
逆に、ユーザー、顧客目線で必要とされる背景や理由を一歩寄り添って理解できれば、良質なテストパターンを記述出来る可能性が高まります。
不要な会議の削除: アジェンダ、自分の発言、会議後の結論、アクションを確認しよう。
アジェンダ、自分の発言、アクションがないのであれば、参加不要な会議の可能性が高です。
会議後に、チームで今後も必要・続けたい会議か投票しよう。ミーティングを改善できないか話し合ってみよう。
チャット、pull reqest、開発現場でのホワイトボードを使ったフェースツーフェースコミュニケーション、ペア作業などで代替できないか検討しよう。
見積りと計画づくり: 後述
不要なドキュメントの削除
席の配置
プログラミング完了ってどういう状態なんでしょうね?
人によって「プログラミング完了しました」の認識がバラバラです。自動テストが含まていたり、含まれていなかったりします。
現場では、(自動テストによる)動作確認までを行って完了とせず、嘘の進捗の「できました」になってることがあります。
したがって、
スクラムの完了の定義を参考に、完了した状態をチームで明らかにしましょう。テストは含まれる?
完了条件にテストが含まれれば、ユニットテストの作成の際にTDDが利用できます。
私は今、開発の計画づくりに参加していません。
計画づくりに参加していないと場合によっては、知らない所で非現実的な仕事量をすることが決まってしまうことがあります。 仕事量が多い場合、テストやコードレビューが省略されることがしばしば発生してしまいます。
開発のコンテキストにおいて、非現実的な仕事量を引き受けけた際、「時間がない」は、テストやコードレビューを省略した手抜きループが発生します。 が、これが後に、後からバグ発覚、度重なる手戻り修正、メンテ不能なコードとさらなる「時間がない」の悪循環の状況を作り出してしまいます。
したがって、
見積もりと計画づくりに取り組みましょう。1-2week当たりの私・私達ができる仕事量(コードレビュー、テスト込み)を把握し、手抜きなしの適量の仕事をこなせるように取り組みましょう。
適正な仕事量で実施できれば、「時間がない」によるテストを書かない、コードレビューがされないことによる、さらなる「時間がない」の悪循環ループを断ち切ることができます。
「割り込み」がテストする時間が失われることがしばしば。
割り込みのコントロールが必要な場合も、一人を犠牲に、対応をとって、残りのメンバーは専念。 割り込みの優先順位を付けて今週やるか次週やるかをきちんとジャッジする。 障害であれば再現テストからTDDを
どこからどこまでの範囲を、どんな目的で、どんな道具を使って、セーフティネットを用意するかを明らかにする。
名前 | 範囲 | 目的 | 道具 |
---|---|---|---|
頻繁なデモによるテスト | 人-マシン | 記述したテストの機能性に関する妥当性確認。新たなテストケースの発見 | デモ環境 |
End to End 結合 | UIからDBまで。ただし外部Webサービスはスタブモック化 | 仕様の明瞭化。ただし記述レベルはPOとシェアしない。 進捗把握。 End to Endの疎通。ただし外部Webサービスとの結合は範囲外 | Request Spec, Capybara, FactoryGirl, webmock |
(Service、Entity) - DB 結合 | Service、Entity DBまで | 複雑なQueryも含めてサービス、エンティティが期待通り動作するか。 ただし、サービスからDBまででドメインよりも、End to Endを優先して記述する方針。 | RSpec FactoryGirl |
Entity, Value Object, Policy, Helper | ユニット。ユニット同士のつながり | コードや設計の改善。設計方針はSOLIDを参照。リーダブルコードを参照。開発の促進。複雑なドメインをテストで明瞭化し、期待通り振る舞うか確認。 | RSpec, RSpec Mock |
スモークテスト |
注意) 開発促進のためのTDDを実施後、補強するテストパターンは改めてレビューと追加・修正を行う。
チームで、テストはそれなりに記述されるようになりました。だが、私は今何かがおかしいことが発生していると感じています。
テストが遅いなど何かおかしなことが起きています。他にも何かおかしなことが起きているのだが、うまく説明できません。
それゆえ
テストの不吉な匂いを参考に、現状のテストを診断してみよう。現状の診断と今後の対策をチームで話し合ってみよう
代表的なテストの不吉な匂いは次です。
サイト先で、現象の原因についても記載されています。
プロダクトオーナーと何を作るかの認識のギャップが大きな問題になっており、 私は、何を作るかについて具体化するコラボレーションを促進するための受け入れテストに取り組むべきと感じています。 (頻繁なデプロイと対話のみでは解消しきれません。) しかし、Cucumber、Fitなどの道具を導入し運用し続けるには、コストが高く、まだ難しいと感じています。
オーナーとの何を作るかで認識のギャップを小さくしたいです。が、Cucumber等のツール導入はハードルが高いと私は感じています。
したがって
表例、Given/When/Thenを使った会話のみ導入しましょう。 ツールの導入は別の機会を伺いましょう。Fit, Cucumberは 自動テスティングフレームワークと同時に エンジニアと非エンジニアのコラボレーションツールであることを忘れないで下さい。 ツールの導入運用コストは抑えつつ、フェースツーフェースのコラボレーションの質の高上が期待できます。 もちろのツール導入のメリットは得られませんが。(記述した仕様の具体例がそのままテストに使え、進捗把握が簡潔明瞭。リグレッション)
ダーティコードは、頭痛吐き気を催し、健康被害をもたらす。動作するきれいなコードを目指して移動する(危険な場所を避ける)ことも選択肢としてはある。 (他の選択は、レガシーコード改善ガイドのように、レガシーコードのある世界にとどまり、頑張って動作するきれいなコード変えていく選択、諦めて過ごす選択。)
各イテレーションでちょっとづつテストを入れていく計画を立てる。 参考に出来るテストが増えれば、先にテストが書きやすくなる。
開発の規律 (DONEの定義)を破って仕事を続けて、身動きが取れなくなる前に。 ゴミコードを量産しない対策、準備をチームで話し合い、部分的なテストの補強、部分的なリファクタリングの猶予期間を設ける。例えば 1week。
TDD=テストですよね。(人が理解しやすいコードや設計の導く技法、デバッカーの代わりにテストと一緒にコードを記述するプログラミングの技法の1つの観点が抜け落ちている。TDDのみでは足らないテストパターンがある。)
失敗レポートのメッセージを読まない
private メソッドのテストの執着
モックテストフレームワークの機能の乱用
練習不足
時間がない
プリント、デバックの多用
Red Green Refactor の学習サイクルが長すぎる
長時間 Red
多数 Red
TODOリストの不在
仕様を把握していない
他者との対話時間不足
テストコードレビューの不在
遅すぎるテストコードレビュー
xUnit Patternsの不吉な匂い
プライベートメッソドをテストしたいんですけど
コードを変えずに、パワフルなモックツールでテスト書きたいんですけど
テストのメンテが難しくてやめてしまいました。
設計者と実装者の分離が阻害要因
テスターとプログラマの分離が阻害要因
物理的・空間的に分離がTDDの学習フィードバックを阻害している。
http://c2.com/cgi/wiki?TestDrivenDevelopment
人の上下関係等によっては、ビジネスサイドと開発サイドで発言力が対等にない場合がある。 よくある失敗シナリオとして、ビジネスサイドの「ターゲット」の希望のみで、実作業者の開発者による「見積り」はなく、 達成不可のスケジュール「コミット」していることが発生している。 その後に起こることは、開発者はテストやコードレビューを諦め、内部品質を犠牲にし、モンスター化ー毒の沼地化したコード残骸に目をつぶりながら、なんとか動くものをだす。 だが、悪夢が待ち受けている(誰も既存のシステムの期待する振る舞いを知らない、吐き気を催す酷いコードで追加修正が困難。 祈りながら追加修正するが、ぶっ壊れて障害対応。使い手も作り手も不幸の結末を呼び寄せる。)。
【実験】を大切にする。早く失敗して、予期せぬ驚きの発見や学びを大切にしよう。 この哲学は、TDDの設計の指針であり、TDDにトライしていく指針でもある。 大丈夫、はじめてのことは、きっと失敗する。失敗しないと学べないんだ。小さく早く失敗し、予期せぬ驚きの発見をして、次の一手を考えよう。
試しに、今から、実プロジェクトで2hTDDを1人ひっそりトライしてみよう。。。。2h TDD試してみたかな? きっと、Red Green Refactorの回転の障害が見つかるだろうが気に病む必要はない。 「あれテスティングフレームワークどれがいいんだろうか?」「インストールは?」「Allテストってどうやって実行するんだろう?」「先にテストを書くって慣れないなー?」「何をテストにかけばいいんだ?」「ついついデバッカー、printの目視で動作確認してしまうよ」「ビルド遅くてRed Green Refactorのリズムできないようー」。。。。etc。 おめでとう! 今、Red Green Refactorの黄金の回転を妨げる要因を、実験を通じて見つけたのだ。回転を妨げる要因は、ひとつひとつ、落ち着いて対処していこう。 さぁ。Red Green Refactorの奇妙な物語のはじまりだ!。
分類候補