makopi23のブログ

makopi23が日々の生活で感じたことを気ままに綴るブログです。

アジャイルサムライ横浜道場 特別編「TDD (再)入門 - 初めての人と挫折した人へ」に参加しました

2015/10/6(火) アジャイルサムライ横浜道場 特別編「TDD (再)入門 - 初めての人と挫折した人へ」に参加してきました。

DoorKeeper
https://yokohama-dojo.doorkeeper.jp/events/31147

以下の書籍をターゲットとした勉強会なのです。

アジャイルサムライ−達人開発者への道−
Jonathan Rasmusson
オーム社
売り上げランキング: 10,743


場所はいつもの横浜市西公会堂です。
参加者は30人くらいでしょうか。特別会&@t_wadaさんということもあって大入りです。いつもより会議室も大きかった。

この日の講演資料は横浜道場のFacebookに公開されていますが、グループに入っている人しか見れないようです。
https://www.facebook.com/groups/yokohamadojo/802470883203394/

ちなみに表紙はこんなカンジ。
20151006_yokohamadojo1.jpg

これまでのTDDのスライドをベースに、きっちりアジャイルサムライの要素をまぶしてくるところがまた素敵。

あと、和田さんのTDDの講演は何回か聞いたことがありますが、これだけじっくりTDDのデモを見たのは初めてでした。
とても勉強になったので、復習を兼ねて今さらながら当日取ったメモを起こしてみる。


注:
下記メモで和田さんの過去の発表スライド(slideshare)をところどころ挿入してますが、この日のスライドとは別物です。
あしからず。

---
■アジャイルサムライ 第5部の章構成
アジャイルサムライ14章のテーマはTDD。第5部は実践の章。
「アジャイルなプログラミングは重複を排除する」と言われるが、12章と14章で両方テストを扱っており重複してるように見える。
でも、著者のジョナサンはきちんと説明するために、意図的に練られた章構成となっている。
14章のTDDは、12章の「ユニットテスト」と13章「リファクタリング」の合わせ技の章となっている。
13章のリファクタリングでは、「既存の振る舞いを変えない」=「テストが動くままにする」。
テスト自動化して、その中で構造を綺麗にするというプラクティスは強力。
これを日々のプログラミングにまぶすことが重要。日々の作業にリファクタリングをビルトインすること。
なのでアジャイルサムライはこの章構成になってる。ジョナサンはよく考えている。

■書籍「テスト駆動開発入門」

テスト駆動開発入門
テスト駆動開発入門
posted with amazlet at 15.10.25
ケント ベック
ピアソンエデュケーション
売り上げランキング: 337,268

持ってる人?と和田さんが参加者に質問したら、4割くらいの人が「テスト駆動開発入門」の本を持っていた。
絶版で、復刊に向けて頑張っている。
この本がTDDの原典。著者はケント・ベックで、XPという本の著者でもあり、JUnitの開発者でもある。

■ 動作する綺麗なコード
偉大な本は偉大な書き出しから始まる。「動作するきれいなコードは、あらゆる理由で価値がある」
テスト駆動開発=動作する綺麗なコードでありたい。
「動作する綺麗なコード」という言葉を分割すると、「動作する」と「綺麗な」に分けられる。
それぞれの反対も考えると4象限に分けられる。
Test Yourself - テストを書くと何がどう変わるか from Takuto Wada

ゴールは右上の「動作する綺麗なコード」。
何もないところを仮に左下の「汚い、(すぐには)動作しないコード」とする。
天才は一直線に左下から右上に行けるけど、僕らはそうではない。2つの道のどちらかを通る。
教科書的な答えは、オレンジの線を通るのが良いと言われる。良い設計を得て、そこからコードに落とす。
最近、オブジェクト指向では設計の復権が起きてるので、この道が増えてきている実感がある。
@t-wadaさんも大学でソフトウェア工学を学んでいたので、オレンジの道だった。キャリアの最初はオレンジの道だった。
でも、オレンジの道には罠がある。
「綺麗なモデル」って何か、分かる人は少ない。
"完璧な設計ができたら、コードを書いていい。完璧な設計ができないなら、手戻りの原因になるからコードは書くな。"
じゃあ、完璧な設計とは何か?と考え始めると、そこから進めなくなる・・・。沼地。完璧主義、羞恥心・・・。
現実世界は無限なリソースとスケジュールがあるわけではないので、コードを書き始めないと間に合わない、という焦げ臭い感じになってくる。
なのでコードを書き始める。すると真ん中の縦線を超えるところでいろんなことがわかる。
考え抜いてきた設計が、コード書いてみると、考えきれてないところがあったり。
最初に設計をきっちりやったけど、ここまで考える必要はなかったな・・・、と逆に気づいたり。
そうやって、手を動かすと気づくことがある。
実際に頭で動くと思ったものも、真ん中の縦線を超えることでいろいろわかってくる。フィードバックがやってくる。
残念ながらソフトウェア開発は「工学」になりきっていない。再現性をきちんと保てる状態ではない。
それは、周りの諸条件がガンガン変化するので、再現性は低くなるから。
最大のフィードバックを得られるのは、コードを書き始める時。現代のソフトウェア開発において、未だに真ん中の縦線のポイントは大事。
真ん中の縦線が大事なら、さっさとそこを越えよう、という青い線の道がでてくる。
こっちも沼地がある。1つは堕落。動いているからいいや、というのが出てくる。もう1つは、恐怖。堕落より重い。
汚いけど動くところまできた。でも、綺麗にする過程で動かなくなっちゃったらどうしよう・・・と考えることがある。
「動くコードには触れるな」という言葉は、いろんな現場で掟として言われてきた。
でも、現代の開発において、プログラミングはある時点で終わり、となることはない。ずっと手を入れないといけない。
コードに手を入れなくても周りの世界はどんどん先にいく。手を入れないと、セキュリティが野放しになっていく。
なので、現代においては、コードの凍結はありえない。手を入れるときに、恐怖と戦わないといけない。
現代の開発のフィードバック量を考えると、早めに左の「動かない」から右の「動作する」に行ったほうがいい。
右下(動作するけど汚いコード)から右上(動作する綺麗なコード)に持ち上げる力、道具があれば、青ルートのほうがいい。
その道具がリファクタリング。
既存のコードを、振る舞いを変えないまま、右下から右上へ。

■ TDDのサイクル
Test Yourself - テストを書くと何がどう変わるか from Takuto Wada

TDDはレッド、グリーン、リファクタリングのサイクル。
一番最初に最小限の設計を行う。最初に、プログラミングに着手できるくらいの設計をする。
紙に書くとか、やることリストを作るとか。
そこから、一番最初にやろうと思うものをピックアップする。それは一番価値あるものだったり、一番簡単なものだったり。
1個だけピックアップする。そのテストコードを書いて実行する。実装がまだないから、テストは失敗する。
実装が無い時にテストをして、コケるところから始める。そこでテストが通ってしまったら、そもそも何かがおかしい。
テストが失敗するの見届けたら、テストが通る最低限のコード書く。テストが通ると緑になる。
動作しているままで、テストが通り続けるまま、中を綺麗にするのがリファクタリング。
この1枚をいろんなスケールで繰り返すのがTDD。

■ アジャイルサムライとTDD
アジャイルサムライでは、「レッドは設計についてしっかり考える出発点だ」と書かれている。
つまり、失敗するテストを書くことは詳細設計に近い。
リファクタリングで、コピペコードとか強引なコードを省いて、綺麗にする。

■ TDDと黄金の回転
Test Yourself - テストを書くと何がどう変わるか from Takuto Wada

これを「黄金の回転モデル」と名前を付けた。この言葉は「ジョジョの奇妙な冒険」に出てくる。名付け親は、今は亡き山城さん?
軌跡が大事。レッド、グリーン、リファクタリングの軌跡。
回転の軌跡が綺麗で、サイクルがうまく回っているほど、効果が出る。
回転が綺麗にならない、というのは、3本の矢印のどれかが短くなる。短くなるのはいつも決まって「リファクタリング」。
「リファクタリングは次のイテレーションでやろう」みたいな後回しが増えると、「きれい」な象限にいられる時間が短くなる。
リファクタリングが短くなる原因は、「リファクタリングはプレッシャーに弱い」という点。
リファクタリングは、機能を追加しないまま綺麗にする。「機能を追加しない」という点をお客さんに説明するのが難しい。
機能が追加されてないのに工数ばかりかかると、「なにやってんの?」となる。
「リファクタリング」というタスクが個別に出た時点でダメ。達成されなくなる。
「リファクタリング」を、他の人に説明するくらいの大きさのタスクになってしまったら負けムード。繊細。
でも、リファクタリングは大事。なので、日々のプログラミングの中にまぶしてやらないとうまく行かない。
「後でやる」はダメ。日々のプログラミングの中にまぶす。
これは部屋の掃除と一緒。出したものを戻す、というのは日々の作業。
それをやらないと後で「大掃除」になって、何も価値を生まないものが出てくる。
汚いコードは、単位時間あたりの機能追加が遅くなる。なので綺麗にすることは大事。
でも説明が大変なので、日々の作業にまぶしてビルトインする。

■ リファクタリングに関する書籍
リファクタリングを独立テーマにした本がある。以下の2冊がおすすめ。
Test Yourself - テストを書くと何がどう変わるか from Takuto Wada


■ TDDのサイクル
Test Yourself - テストを書くと何がどう変わるか from Takuto Wada

TDDはサイクルである。さまざまなスケールでサイクルを繰り返す。
ユニットテストの外にも、受け入れテストのサイクルがある。
受け入れテストは、ストーリーをDoneにするために通らないといけないテスト。
受け入れテストの分野は、CucumberとかSeleniumなどのツールが最近は普及してきた。

■ TDDのサイクル その2
Test Yourself - テストを書くと何がどう変わるか from Takuto Wada

更に、受け入れテストの外にも「頻繁なリリースとデモ」というサイクルがある。
サイクルが多重になっている。アジャイルは自己相似形を好む。

■ テスト駆動開発のホットスポット
最近、ケントベックはFacebookの技術顧問をやっているが、Facebookにテストの記事を書いている。
Test Yourself - テストを書くと何がどう変わるか from Takuto Wada

↑は、テスト駆動開発のホットスポットの図。TDDはどのようなもので、どこを住処にしているかを表している。
3つの軸がある。


(1) SCOPE
やろうとしていることの大きさ、影響の大きさを示している。
文法エラーが無い、というレベルから、社会にインパクト与える、というレベルまでの目盛りがある。

(2) CLARITY
明快さの軸。知らん→定量化→しきい値→バイナリ(2値)

(3) FREQUENCY
頻度の軸。
---

テスト駆動開発は、どこが住処かというと、
・影響範囲(SCOPE)はデプロイできるし、動くソフトウェア、くらい。金を生むかどうか、までは行っていない。
・頻度(FREQUENCY)は、TDDは数秒に1回くらいの頻度でテストを動かすので、頻度は最高レベル。
・明快さ(CLARITY)も、一番向こうまで振り切れている。動くか動かないか、の2値レベル。
これがTDDの居るところ。

デモ
使っているプログラミング言語に挙手してもらったところ、どれも微妙だったので、Javascriptでやることに。
お題はFizzBuzz。海外では入社試験でよく使われる。
極度に緊張する場合だと、5%くらいの正答率だそうで、それに関する有名なブログがある。
TDD のこころ @ OSH2014 from Takuto Wada

宗教上の理由で、エディタはEmacsを使う(笑


■ストーリーの分割
まず、お題のストーリーを分割する。分割、整理、並び替え。まず文で分割してみる。
1から100までの数をプリントするプログラムを書け。
ただし3の倍数のときは数の代わりに「Fizz」と、
5の倍数のときは「Buzz」とプリントし、
3と5両方の倍数の場合には「FizzBuzz」とプリントすること。
「1から100までの数」と「「プリントする」という文は複雑なので、後回しにする。
お題に無いが、「その他の数のときはその数を返す」というのを文書化して、先頭に持ってくる。
「プリントする」は後回しにしたので、「返す」にする。そうするとテストできる感じがしてくる。

■ テストコード
テストファイル名を考えるところから設計は始まっている。今日はFizzBuzzTestにしよう。
「その他の数の時はその数を返す」
それってなんだ?となる。頭でわかってても、文にしてみると、そういうのがわかってくる。
「その他」を、まず「1」にしてみよう。
テストコードは、まずゴールから書く。そのゴールのコードの上に、コードを付け足していく。
IDEを使うと、最初にゴールを書くと、足りない要素をガンガン指摘してくれる。
「1の時は1を返す」と「3の倍数の時はFizzを返す」で、型が合わない、と気づく。
なので、「文字列として返す、という仕様なんだな」ということに、テストコードを書き始めると早い段階で気づくことができる。
疑心暗鬼になったら、慎重な道を取る。

■ 仮実装による、テストのためのテスト
テストが疑わしいので、テストがちゃんと動くかな、というのも含めて、テストを通すための最低限の実装をする。
「1の時は1を返す」をreturn 1;と実装してみる。1が返るテストなのだから、実装で1を返す。
この、直値を返す実装を、「仮実装」と言う。疑心暗鬼な状態を解決するための実装。
プロダクトコードが1を返すだけのコードなんだから、もしテストが通らなかったら、テストコード側、つまりテストフレームワーク側がおかしいということになる。
「テストコードに間違いがあったらどうしよう」という疑心暗鬼に対し、テストコードのテストコードは、実装コードにさせる。
実装コードに誤りを意図的にいれて、テストが落ちることを確認する。
実装コードがおかしいのにテストが落ちない、というなら、テストコード側がおかしいはず。

■ ミューテーションテスティングと三角測量
「ミューテーションテスティング」というのは、テストスイートの十分さを測定するための手法。
テストコードを先に書いて、次にプロダクトコードを return 1 と書いたのは、テストコードをテストするためだった。
これでテストのためのテストが終わったので、次は1以外の数値でもいけるようプロダクトコードを修正する。
これを「三角測量」という。1だけのテストだと安易過ぎるので、2という別のデータを使ったテストを足す。
別のデータを使ったテストを足すには、2パターンの足し方がある。
縦にAssertを増やすか、メソッドを増やすか。

■ Assertion Roulette アンチパターン
縦にAssertを増やすと、テストが途中で失敗したら、残りのテストは実行されない。
どのAssertionでテストが落ちたのかわからなくなる。
なので、迷ったらテストメソッドを増やすこと。
テストごとにアサーションを1個に絞ることを目指してください。1:1対応にすると、どこで落ちたか探す必要がなくなる。

■ アジャイルサムライにおけるTDD
三角測量はテスト駆動開発のローギアのチェンジ。なんらかの自信がないときに慎重にやる場合に使う。
アジャイルサムライにも、テストをグリーンにする話として
とにかくテストに成功するコードを書く。実装の最終形を思い描けるなら、一気に仕上げてしまえばいい。
そこまでの自信がなければ、まずはテストに成功する程度の実装だけで構わない。

とある。
よって、3の倍数のテストを1,2,3,6の順で試したのは、「テストに成功する仮実装+三角測量」という手法で進めたためである。
それを経験したので、5の倍数のテストは、上の文章にあるように"一気に仕上げる"方法を取った。
テストを使って不安を明確に落とし込んでいくのがTDDだが、個人差が出る。
スキルのある人はガンガンいけるし、自信ない人は歩幅を小さくして前進すればよい。
自信が過剰なら、テストはちゃんと赤くなってくれる。
自信と歩幅とレッド/グリーンが揃っているのが、一番バランスが取れている時である。
赤くなるとおもったのに赤くならない、とか、フィードバックが自分の思ってる姿が一致してない、だと、バランスが取れてない。
それは個々人の状況によって変わる。

■ リファクタリング
途中段階のテストコードは、個別の値に対してテストしてるだけ。不安を解消していっただけで、リファクタリングされていない。
なのでリファクタリングをする。
プロダクトコードだけでなく、テストコードもリファクタリングしないといけない。
Assetを羅列したテストコードを後で見ても、「あぁ、あの時は追い詰められてたんだな・・・」くらいしか読み取れない。
なので、覚えているうちにリファクタリングをする。

■ 仕様とテストコードの構造を合わせる
テストコードに入れ子の階層構造を取り入れて、仕様とテストコードの構造を合わせる。
仕様と具体例との階層構造。
3の倍数のときはfizzを返す
 3のときfizz
 6のときfizz
5の倍数のときはbuzzを返す
 5のときbuzz

と、段階的構造化をする。でも、上記の構造化は対称性の破れがある。
3の倍数のテストは2件やったのに、5の倍数のテストは1件しない。
なので、せめて対称性をもたせよう。「10の場合はbuzz」というのを追加する。
最低2件はテストしよう。
階層構造が無いような平らなテストで終わっては、チーム開発ではダメ。
自分の不安を解決する最初としては正しいが、チームや半年後の自分にとってはいいものではないので、階層化して整理すること。

■ おわりに
「黄金の回転」を覚えて帰ってください。
リファクタリングの矢印が繊細で短くなりがちなので、ちゃんとキープすること。

gihyo.jpでTDDの連載がある。他のエンジニアにTDDを伝えるのに、「ここ見といてよ」と使える。
http://gihyo.jp/dev/serial/01/tdd/0001

TDDは練習量がうまさに繋がる。TDDは、才能でなくスキルです。

★感想:
TDDのデモがすんごく参考になった。
さすがワイルドサバンナと言わざるをえない。尊敬するエンジニアの1人です。
あと、和田さんが影響を受けたというケント・ベックのTDD本、復刊されたらぜひ読んでみたいと思うのです。

和田さん、企画してくださったたくぼんさん、ありがとーございました。
関連記事
スポンサーサイト

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://makopi23.blog.fc2.com/tb.php/189-98c8b8b1
この記事にトラックバックする(FC2ブログユーザー)

FC2Ad