Hatena::ブログ(Diary)

くろまほうさいきょうでんせつ RSSフィード

2011/07/01 (金)

恥知らずなTDD使いがいた!

俺はRDDを使い手なんだがプロジェクトリーダーがが残念なことにTDDを使ってきたので「お前それで良いのか?」と言うと「何いきなり(テスト書かずに)実装してるわけ?」と言われた。
俺の前プロジェクトチームがTDDの熟練者なのだがおれはいつもデスマーチにするから気の毒になったので聞いただけなんだがむかついたので「お前中身が空のテストでボコるわ・・」と言ってプロジェクト開始直後にバグを溜めてコミットしたら多分リアルでビビったんだろうな、、カバレッジ測定してきたから無視してカカッとコミットしてから障害だしたらかなり青ざめてた
おれは一気に次の実装をしたんだけどリーダーがテンパってておれの作業を見失ったのか指示出してこなかったから独自インデントでコーディング規約を崩した上についげきのオレオレデザインパターンでさらにプロジェクトへのダメージは加速した。
わざとチームから距離をとり「俺はこのまま納期に間に合わなくてもいいんだが?」というとようやく必死な顔してなんか部屋のはしっこにプログラマ増員してきた。
チームは必死に仕事するが、時すでに時間切れ、マジックナンバーと謎のif分で固めたスパゲッティにスキはなかった
たまに来る効果的なリファクタリングもコンフリクトで撃退、終わる頃にはズタズタにされて白髪の増えたメンバーがいた

↑アンチパターンとしてのRDD

ふと思ったこと

xUnit,Jenkins,tracなどのアジャイルプロセスのためのツールを使っていないプロジェクトがありました。
でも、こまめなデプロイ(機能リリース)を繰り返してCIっぽくうまくいっていたことに気付いたので。

RDD (Release Driven Development) リリース駆動開発

リリース駆動開発とは

とりあえずリリースして様子を見る開発手法である。
手戻りに強くすばやいリリースが少ないリソースで可能。だが一歩間違えると単なるTDDのアンチパターンになるという諸刃の剣。素人にはお勧めできない。

RDDで開発を行う理由

既にレガシーコードのシステムが稼働中

テストを書くためには大掛かりなコードの修正が必要だったり、進め方を変えるのに偉い人の判断が必要だったり、なんかいろいろと壁があってTDDに切り替えられない。
TDDで開発を進めるのはプログラマ個人の問題だったりするのでそんなに問題にはならなそうですが、既存のものにテストを書いていくとなると話が違います。

開発担当者が全体を把握しているので何とかなる

長い時間をかけてコードが育つのを、特定のエンジニアがずっと見てきた場合。てゆか育ててきた場合。
ハウルの動く城みたいなコードベース。 誰が見てもとっちらかってるけど作った本人は中身をよく把握してて、掃除されると逆に大変になるみたいな。

ツールじゃないんだ、人なんだ

TDDやCIの手法やツールなしにうまいことプロジェクトが回っていた理由。

あとでかく。
→ 書いた RDD (Release Driven Development) リリース駆動開発 - くろまほうさいきょうでんせつ

2011/06/18 (土)

既存システムでTDDするのが難しい理由

TDDしたい、CIしたいと思ってもなかなか導入できない。何でだろう?
PHP製WebアプリケーションでのTDDを学び始めた現時点の気持ちまとめ。

Seleniumを使うような高いレイヤーのテスト

どんなテストを書けばいいのかわからない

例えばDBから商品情報取ってページ生成する場合。

  • 商品カテゴリごとに異なる趣きのページを作るのでそれぞれにviewのテストを書いたとする
  • 各ページ内の商品詳細URLにパラメータが追加されることになった
  • URL生成は共通のモデルで行っている
  • 修正は一ヶ所で簡単なもの

だったとしてもviewのテストはそうは行かない。
先に用意したテストケースを全部書き直さなきゃならない。

小さな変更にかかるコストが大きくなる

単純に時間がかかるというより
めんどくさくなる → どうせやらなくなる

という思い。

コントローラーとか中間くらいの層のテスト

viewよりは下、ユニットよりは上、複数モデルを組み合わせて使うような部分とか。

リファクタリングしないとテストできない

テスト用DBとかモックとか使う必要がある点で敷居が高いのと、そもそもモックが使える様にする為に、派手にリファクタリングして依存性を外から注入できるようにしないといけない。

勝手にリファクタリングできない

今のコードベースばテストはしづらいものの、統一された規約や作法、設計思想に基づいて作られているので一部だけ勝手にリファクタリングなんて出来ない。アーキテクトの意思決定が必要。 実践した経験も無くその効果も良くわからないのに提案もくそもない。

一からやり直したくなる病

というか、そこまでがっつり変更するなら初めからこれらのテストが機能として組み込まれたフレームワークに乗り換えて心機一転の機会を私待ーつーわ。

という思い。

モデル内のメソッドに対するユニットテスト

やっぱりテストできない

1ドメイン1モデルクラスみたいな感じでメソッドがまとまってて結構な数のprivateメソッドがあったりする。
PHP5.3だったらリフレクションでprivateメソッドも実行できるが、うち5.2だし!
オブジェクト指向的には1クラス1責務なんだろうけど、これに従って大量にクラス分割する様なリファクタリングするには相当な覚悟がいるよね・・・
というかそもそも1ドメイン1クラス設計もありなんじゃないか。

という思い。

まず手をつけるなら最も低いレイヤーのユニットテスト

はじめの一歩はここが本命じゃなかろうか

とりあえず手がかりをつかむために、モデルクラスの中のごく一部のメソッドからでも。privateなのを試しにpublicにしちゃうとか、クラス分割できるならちょっと一瞬やってみちゃうとか、もしくはユーティリティ的にstaticに定義されてる関数とか、そのへんを狙えばテストを書いていけそう。

保護するためのテストという考えを捨てる

気持ちを切り替えて敷居を下げる。
あれもこれもassertしなきゃ、こんな中途半端なテストじゃ足枷にしかならないんじゃ、と考えるのをやめる。設計を整理して仕様を明確にするために最低限のテストを書くと考える。

  • コメントで「//このフラグは○○なので注意」みたいなことを書きたくなったらそれをテストに書こう
  • デバッグでprint_rとかしたくなったらそれをテストに書こう

こんな感じ。

2011/06/13 (月)

アジャイルプラクティス 達人プログラマに学ぶ現場開発者の習慣 を読んだ


アジャイルプラクティス 達人プログラマに学ぶ現場開発者の習慣

アジャイルプラクティス 達人プログラマに学ぶ現場開発者の習慣



45個のプラクティスの紹介が、それぞれ悪魔の誘惑に始まり天使のささやきで終わる。具体例と実行時の気持ちまでが説明されていてとても楽しく読みやすい。(日本語訳がとても丁寧に行われたように思えます)
以下、本を読んだ感想やふと思ったこと。

アジャイルは開発手法ではない

アジャイルはチームを構成するメンバー各人の心構え、仕事に臨む態度である

・・・ここまで言い切ると語弊があるかもしれないが、この本を読むまではアジャイルというのがこんなにも人間にスポットを当てた方法論だとは思ってなかった。

TDD

TDDのいいところは自動的にテスト行われてデグレが自動的に見つかるとかいうところにあるのではない。
テストフレームワークにあわせてそれを意識して開発を行うことで、開発者の頭の中が整理されてアプリケーション(プロジェクト)自体が非常に整った、メンテナンス性の高いものになるところにある。
偉い人が「導入するぞ」って言うのを待たずとも、個人でできることはいろいろある。

レガシーの問題点

通常、ユニットテストによるテストを意識したモジュール間の依存性が低い状態になっていないため、テストしにくく、結合度の高さ故、変更を加えにくく、予期しない箇所に影響が出やすい。
そのせいでストレスがたまる、なんか怖くて微妙に手がすすまない。

アジャイルのなにが優れているのか

技術者にとって

アジャイルの肝は各メンバーが前向きに生産的に常に前進しようとするところにある。
アジャイルの提唱するものが、よりよくあろうとする技術者の性質と相性がよく、アジャイルプラクティスにしたがって開発していると心地よいとかそんな感じなんじゃなかろうか。
ただし、そんなにやる気もなく、言われたことだけやっていたいとか、向かない人もいる。

顧客にとって

より良い製品を得られる。
ただし、依頼を投げたらあとは勝手にやってほしいとか、そういう場合は向かない。
というか、この本にあるようなアジャイルなメンバーがそろったチームと、彼らといい関係を築けるような顧客だったら別に開発手法がウォーターフォールだろうがなんだろうが成功する気がする。

単に正しいやり方を適用すればいいってわけじゃない

16 頻繁なデモでフィードバックを得る
コードの変更がそうであるように、開発方法を変えようとする場合はそれが現在どのように機能しているか、なぜそうなっているのかを理解しなくては、効果的に変更を行うことはできない。

新しい手法だけ持ってきて「これで行くから」的なゴリ押しに走る人は肝に銘じておいてほしい。誰だって好き好んでレガシーでいまいちな状況に甘んじているわけではない。
いろんなのっぴきならない理由があるのです。

バックログの重要性

23 ありのままの進捗を計測する
見積もりの腕を上げるために。
最初からうまく行くはずもない。とにかく見積もってみよう。そしてその見積もりを記録し、実際にかかった時間と比較しよう。
バックログを活用して記録するのだ。回数を重ねれば上達する。

社内システムの保守とかで特に締切が付いてこない作業をしてるときでも、漠然と作業を進めるのはもったいない。見積もりの訓練と思って計画と振り返りを行うべし。
UnitTestがない場合もバグがあったらどこかにまとめておくと役に立つ。
(TDDの導入を進言するために過去のバグの分析をしたら自動化されたテストがあったとしても回避できなかったであろう問題ばっかりだった、とか :P)

まとめ

楽しく読めました。
悪魔のささやきにすごく共感してしまう・・・