SlideShare a Scribd company logo
#ccc_r11
私がTDD出来ないのはどう考えても
お前らが悪い!
~エンタープライズJava開発におけるTDD適用の勘所~
2014/11/15
大中浩行
#ccc_r11
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
突然ですが、TDDとは?
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
TDD三原則 (Uncle Bob)
• 失敗する単体テストのコードを書く前に、製品
のコードを書いてはいけない
• コンパイルが通り、適切に失敗する単体テスト
が通るまでは、次の単体テストを書いてはなら
ない
• 現在失敗する単体テストが通るまで、次の製品
コードを書いてはならない
「Clean Code アジャイルソフトウェア達人の技」
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
という原則は原則として踏まえた上で、現場に
TDDを導入するときに何を考え、どう行動した
かというのが今日のテーマです。よろしくお願
いします。
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
アジェンダ
• なぜTDDするのか
• どうTDDするか
• 技術的な各論
• なぜTDDするのか(again)
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
• 大中浩行(Ohnaka,Hiroyuki)
• TDDBC横浜(2011~2013)主宰
• yokohama.devtesting / devtesting-ja
• #agilesamurai #横浜道場
• Twitter @setoazusa
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
• グロースエクスパートナーズ(株)
• 大手通信事業者の法人向けサービス開発プ
ロジェクト
• TDDの導入、DevOpsの推進、プロジェク
トメンバーのフォローなどがお仕事。
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
アジェンダ
• なぜTDDするのか
• どうTDDするか
• 技術的な各論
• なぜTDDするのか(again)
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
「テストがないコードはレガシーコードだ!」
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
「いまさら聞けない」
http://www.atmarkit.co.jp/ait/articles/1410/17/news034.html
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
各所で猛威を振るうt_wada.png
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
テストを書かなければプログラマーにあらず?
その一方で…
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
TDD is dead.
http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
「TDDを諦める」
http://takashiba-labo.hatenablog.com/entry/2014/10/17/003431
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
「テスト駆動開発はなぜ流行らなかったのか?」
http://peace.2ch.net/test/read.cgi/tech/1389568154/
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
どうしてこうなった
• もともとTDD(というよりアジャイル開発)に
関連するプラクティスはそれぞれが密結合し
ていて、TDD単独で理解するのが難しいとい
うのはありますが…
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
「テスト」と責任の関係
• テストという工程は、その性格上、品質保証
や、成果物への責任と強い関係をもっている
• 「テストを書くべきだ」という論に明快に異
を唱えられる人は少ない
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
• 開発プロセスの望ましい姿を論じていたはず
が、道義的な責任の問題になってしまう
• テストを書く人と書かない人の間の感情的な
対立は、何も生み出さない
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
「TDDやれば偉いわけじゃない」
http://b.hatena.ne.jp/entry/232721484/comment/t-wada
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
総合力の必要性
「テストを書く」ということは、CIや静的解析、
コードレビューやペアプロなど、チーム開発の
ためのプラクティスと連携して、初めてその力
を発揮する。
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
では、なぜTDDするのか
…?
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
一つの答え
• 「動作するきれいなコード」のために
「テスト駆動開発入門」
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
テストファーストにこだわらない
• 表層的に、テストを先に書くかどうかではな
く、テストを書くこととプロダクションコー
ドを書くことが統合されているか
• そして、テストが開発の助けになっているか
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
アジェンダ
• なぜTDDするのか
• どうTDDするか
• 技術的な各論
• なぜTDDするのか(again)
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
プロジェクト概要
• 大手通信事業者の法人向けサービス開発
• メンバー 開始時11名→現在21名
• 開発プロセスはスクラム
• サービスインまでの開発期間7ヶ月
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
プロジェクト概要
• Backbone.js(CoffeeScript) + Spring MVC
+ Spring Batch + Hibernate(JPA)
• ユニットテスト総ケース数3800ケース
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
立ち上げ時の状況
• クライアントの開発部隊+インテグレーター
2社で1チーム
• 初めて顔をあわせるメンバーが多い
• とにかく手探り
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
ペアプロ
• ペアを組んでユニットテストのコーチング
• とことんつきあう
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
テストファーストにこだわらない
• イテレーションの中で実装とテストが完結し
ていれば、テストファーストでなくてもよい
ことに
• テストがあることのメリットを実感してもら
う
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
ユニットテストを過信しない
• フェイルファストしてないユニットテストが、
しているテストと比べて信頼性を欠くのは事
実
• 自動でないテストも重視
• ユニットテストから漏れるバグがあることを
受け入れる
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
全部をテストしない
「サーバーサイドはばっちりテストを書きます。
フロントエンドも自動テストして、end to end
のテストもSeleniumで自動化します」
「落ち着いてください」
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
• まずはサーバサイドのユニットテストの整備
から
• サーバーサイドはAPIのエンドポイントとな
るController/Serviceクラスについてはテス
トを網羅
• 後は必要に応じて
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
100点を目指さない。優先順位をつける
ユニットテストの5つの規則(F.I.R.S.T)
• 再現性がある (Repeatable)
• 独立している(Independent)
※ほか、高速である(Fast)/自己検証可能(Self-Validating)/適時性(Timely)
「Clean Code アジャイルソフトウェア達人の技」
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
スキル・ノウハウの共有
• スプリントごとにペアプロのペアを組み替え
• アトラシアンフルスタック
(JIRA/Confluence/Bamboo/Stash)による
情報共有
• 「伝言ゲームソリューション」
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
しかし問題も…
開発が進むにつれ、たまっていく技術的負債
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
技術的負債
• 意図がはっきりしないテスト
• テストメソッド名とやっていることが一致しな
いテスト
• コピペ
• モックの使いすぎ
• etc…
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
技術的負債の返済
• 改善サイクルをまわす
• スプリントごとの振り返り(KPT)
• Tryをちゃんとタスク化する、工数を割り振
る
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
結果
• リリース判定会議をスムーズにクリア
• リリース直前に殆どのメンバーが定時帰り
• サービスイン後も定期的にリリースを実施
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
どうしてうまくいった?
• RESTfulのAPIを定義した上で、フロントエンド
とサーバサイドでそれぞれ実装して、それを結
合するというプロセスだったので、ユニットテ
ストでサーバーサイドの動作を確認するという
アプローチが自然だった
• Controller層とService層もModuleを分割してい
たので、同じ事が言える
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
「信頼で結ばれた共同体」(※)
• 「2人目」の存在
• 問題を指摘するとちゃんと次のスプリントに
のせてくれる
• 人対人でなく、問題対私たち
• 「いいもの」をつくるという合意
※「組織パターン」から
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
アジェンダ
• なぜTDDするのか
• どうTDDするか
• 技術的な各論
• なぜTDDするのか(again)
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
お品書き
• スローテスト
• データベースを使うテスト
• Controller層のテスト
• モック
• フロントエンド
• End to Endのテスト
• 作業をテストする
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
スローテスト怖い
スローテストによる開発リズムの悪化
→ビルドの通らないコードのpush
→CIの信頼性低下
→デリバリーのフロー崩壊
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
よくあるスローテスト対策
• 組み込みデータベースを使う
• データベースをモックする
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
だがちょっとまってほしい
• そもそも、「データベースを使うと遅い」の
であれば、データベースって業務に使えない
です…
• 「データベースを使うテストは遅い」は都市
伝説?
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
実例(その1)
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
実例(その2)
https://twitter.com/setoazusa/status/194746629159526400
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
• Java開発の場合は、スローテストの原因になる
のは、コンテナの立ち上げ
• ユニットテストの望ましい姿(独立性)からは外れ
ますが、Spring Frameworkの
SpringJUnit4ClassRunnnerはContainerの
Contextをキャッシュする実装になっているので、
初期化コストはおさえられる。
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
何がデータベースを使うテストを難しくするのか
• ネックとなるのはテストの実行時間よりも、
テストデータのメンテナンスに必要なコスト
が失わせる、テストのリズム感
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
Excelを捨てよ、街へ出よう
• IDEで作業しているときに一々Excelたちあげ
るのたるいし…
• Excelでファイルを開いているためにIDEがビ
ルドエラーになるのってあるあるですよね?
• そもそも分散バージョン管理しているとマー
ジできない!
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
XMLだけど自動生成すれば問題ないよねっ
• 本当はYAMLなりJSONにしたかったのですが、
DBUnitとの相性との関係で。
• テストデータ作成時は開発者のテストデータに
一度投入した後、mavenプラグインでエクス
ポートする方法を採用
• ただ、mavenでエクスポートするのはあまり使われ
てないみたい..
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
データベースのアサーション、どうやろう…
• データベースの更新系処理は、データベースの
テーブル全体をアサーションするのがセオリー。
• しかし、テストに関係してない、更新されない
データまで期待値に含む必要があるため、テス
トデータのメンテナンスコストが増大する問題
がある。
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
• データベースの更新・削除の前後で、テーブ
ルの状態の差分を取り、その差分をアサー
ションするようにDBUnitをカスタマイズ。
(デルタアサーション)
• このことのより、期待値のデータのメンテナ
ンスコストを削減
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
データベースマイグレーションはTDDに必須
• 開発者の相互の環境がテスト実行に影響を与
えないようにするため、開発者ごとに
Vagrant でデータベースを用意。
• ローカル/CI/開発環境/ステージング/本番の
スキーマ構成を管理するため、データベース
マイグレーションツールを使用。
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
MyBatis Migrationsによるマイグレーション
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
Controller層のテストあるある
Controller層はユニットテスト書けなくはない
けど、ブラウザから叩く時の条件とは違うし、
struts-config.xmlが正しいかは結局Tomcat起
動しないとわからないし…
だったらユニットテストいらないじゃん!
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
Controller層のテスト
• End to Endになるべく近い条件でテストした
い
• Spring MVC Test Frameworkはhttpのリク
エストを高い精度でシミュレートできるため、
これでControllerをテスト
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
Spring によるRESTful APIのテスト
mockMvc.perform(get("/company/fieldnotes.jp/users/hiroy
uki@fieldnotes.jp"))
.andExpect(jsonPath("$.id",is("hiroyuki@fieldnotes.jp")))
.andExpect(jsonPath("$.firstName",is("Hiroyuki")))
.andExpect(jsonPath("$.lastName",is("Ohnaka")))
.andExpect(status().isOk());
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
モックした場合のコンテナー汚染問題
• Dependency Injectionしたコンポーネント内の
オブジェクトをモックした場合、Springのコン
テナー内のオブジェクトが汚染される問題
• モックを使うテストケースに@DirtyContextを
つければ回避できるが、テストが目に見えて遅
くなるため @After のメソッドの中でオブジェ
クトを差し戻すように修正
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
フロントエンドのユニットテスト
• サーバーサイドのみのテストでもフロントエ
ンドに良い効果は及ぼせる
• フロントエンドを改修する時に、サーバーサ
イドをテストでガードできているため、リグ
レッションの検証範囲を限定できる。
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
とはいうものの…
• 開発が進むにつれ、フロントエンドにテスト
がないことよりサーバーサイドとのリズムの
ずれが顕在化
• 結合する時のテストの粒度のずれ
• リファクタリングのしやすさのずれ
• ブランチのマージする時のリスクのずれ
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
「安西先生、テストが書きたいです…」
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
フロントエンドのテストへの取り組み
• mocha でモデルのバリデーションのテスト
から、そこから徐々に拡大
• CasperJs + mocha でRestfulのAPIをモッ
クした状態での機能テスト
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
• もともとGruntでビルドするようにしていた
ため、テスティングフレームワークの組み込
み自体は意外にすんなりいった
• ただ、テストの書き方は現在も試行錯誤中
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
end to end のシステムテスト
• リグレッションテストは、イテレーション(1
週間ないし2週間)の最後に、開発メンバー全
員で手動で行うことによって実施
• テストケースはTestLinkで管理
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
end to end レベルのシステムテスト
• プロジェクト終盤から、Geb+Spockによる
自動リグレッションテストに徐々に移行
• 現在は、自動リグレッションテストと手動リ
グレッションテストが共存している状態
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
デプロイ自動化の問題
• プロジェクトのミッションとしてDevOpsの
推進があり、その一環として自動デプロイを
実施
• 自動デプロイの実装時に、スクリプトの問題
による不具合・リグレッションが多発
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
ServerSpecによるデプロイ作業の検証
ServerSpecでデプロイスクリプトの動作を検証
し、CIサーバーから各環境に対してテストを実
施することで事態を改善
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
describe service('jboss') do
it { should be_enabled }
it { should be_running }
end
describe command("wget -O - http://localhost:8080/service/status") do
it { should return_exit_status 0 }
end
describe "setting.propetiesがデプロイされていること" do
describe command("diff #{RESOURCES}/setting.properties
#{JBOSS_HOME}/properties/setting.properties") do
it { should return_exit_status 0 }
end
end
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
• サーバー環境に対する操作等の正当性をテス
ティングフレームワークで担保するのは、リ
ターンを得やすいためおすすめ
• 他にも、環境ごとのプロパティファイルの項
目に不整合がないかの検証をCI環境で実施す
るなど(RSpecを使用)
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
アジェンダ
• なぜTDDするのか
• どうTDDするか
• 技術的な各論
• なぜTDDするのか(again)
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
荒みきったコード
疲弊しきった現場
爆弾処理のような
リリース
http://www.flickr.com/photos/okinawa-soba/2951808529/
http://www.flickr.com/photos/22719239@N04/2246462044/
http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:Bomb_neutralizing_EOD_9.jpg
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
もうウンザリです。何も改善できません。
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
もうウンザリです。何も改善できません。
「しかし、私たちにはプログラミングをする本当の理由
があるはずです。」
「もし、自分や同僚がプログラミングを楽しめるなら、
どんなシステムに取り組んでいるかは重要ではありませ
ん。そのシステムに対してきちんとした仕事ができるは
ずで、そうでなければ待っているのは落胆です。そう
なってしまっては何の楽しみもありませんし、私たちは
そんな目に遭うべきではありません。」
「レガシーコード改善ガイド」
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
「君が質の高いソフトウェアを届けることは誰
にも止められない。君が現場に立って、お客さ
んに向けてプロジェクトの状況と、プロジェク
トに必要なことを誠実に伝えることも誰にも止
められないんだ。」
「アジャイルサムライ」
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
なぜTDDするのか
私の場合…
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
「君にも君を動かしているものがあるでしょう?」
あなたの場合…
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
「世界よ 変われ」(※)
• ミッションを共有する仲間が集うコミュニ
ティで、
• プログラマーが一人一人知恵を持ち寄り、議
論し、勇気づける場が出来たときに、世界は
変わる
• そう思う。
※いきものがかり 「NEW WORLD MUSIC」
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
あなたがコミュニティです
• キミのいる世界、わたしのいる世界
• 自分が完璧なエンジニアでないことを認める
• 問題を他人事にしない。真摯に向き合う
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
「信頼で結ばれた共同体」のために
• スキルの有無/キャリアの長短を人を計る尺度に
しない
「新人だから知らないと思うけど」なんてとんでもない!
• IT技術者としてのバックグラウンドを尊重する
• ペアの意志決定を尊重する
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
この発表での結論
• TDDを導入するのに必要なのは、チームをつ
くること。
• チームをつくるということは、コミュニティ
をつくるということ。
• そのことに、ウォータフォールもアジャイル
も関係ないと思います。
#ccc_r11
Copyright 2014 Hiroyuki Ohnaka
#ccc_r11
最後に
• 自分たちのやっていることがTDDのプラクティ
スに沿っているかどうか、そのことはあまり気
にしていないです。
• 答えは、みなさんの現場にあります。
• Have a nice Testing!
• ご静聴ありがとうございました。

More Related Content

JJUG CCC 2014 fall 「私がTDD出来ないのはどう考えてもお前らが悪い!」~エンタープライズJava開発でのTDD適用の勘所~

  • 2. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 突然ですが、TDDとは?
  • 3. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 TDD三原則 (Uncle Bob) • 失敗する単体テストのコードを書く前に、製品 のコードを書いてはいけない • コンパイルが通り、適切に失敗する単体テスト が通るまでは、次の単体テストを書いてはなら ない • 現在失敗する単体テストが通るまで、次の製品 コードを書いてはならない 「Clean Code アジャイルソフトウェア達人の技」
  • 4. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 という原則は原則として踏まえた上で、現場に TDDを導入するときに何を考え、どう行動した かというのが今日のテーマです。よろしくお願 いします。
  • 5. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 アジェンダ • なぜTDDするのか • どうTDDするか • 技術的な各論 • なぜTDDするのか(again)
  • 6. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 • 大中浩行(Ohnaka,Hiroyuki) • TDDBC横浜(2011~2013)主宰 • yokohama.devtesting / devtesting-ja • #agilesamurai #横浜道場 • Twitter @setoazusa
  • 7. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 • グロースエクスパートナーズ(株) • 大手通信事業者の法人向けサービス開発プ ロジェクト • TDDの導入、DevOpsの推進、プロジェク トメンバーのフォローなどがお仕事。
  • 8. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 アジェンダ • なぜTDDするのか • どうTDDするか • 技術的な各論 • なぜTDDするのか(again)
  • 9. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 「テストがないコードはレガシーコードだ!」
  • 10. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 「いまさら聞けない」 http://www.atmarkit.co.jp/ait/articles/1410/17/news034.html
  • 11. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 各所で猛威を振るうt_wada.png
  • 12. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 テストを書かなければプログラマーにあらず? その一方で…
  • 13. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 TDD is dead. http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html
  • 14. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 「TDDを諦める」 http://takashiba-labo.hatenablog.com/entry/2014/10/17/003431
  • 15. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 「テスト駆動開発はなぜ流行らなかったのか?」 http://peace.2ch.net/test/read.cgi/tech/1389568154/
  • 16. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 どうしてこうなった • もともとTDD(というよりアジャイル開発)に 関連するプラクティスはそれぞれが密結合し ていて、TDD単独で理解するのが難しいとい うのはありますが…
  • 17. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 「テスト」と責任の関係 • テストという工程は、その性格上、品質保証 や、成果物への責任と強い関係をもっている • 「テストを書くべきだ」という論に明快に異 を唱えられる人は少ない
  • 18. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 • 開発プロセスの望ましい姿を論じていたはず が、道義的な責任の問題になってしまう • テストを書く人と書かない人の間の感情的な 対立は、何も生み出さない
  • 19. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 「TDDやれば偉いわけじゃない」 http://b.hatena.ne.jp/entry/232721484/comment/t-wada
  • 20. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 総合力の必要性 「テストを書く」ということは、CIや静的解析、 コードレビューやペアプロなど、チーム開発の ためのプラクティスと連携して、初めてその力 を発揮する。
  • 21. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 では、なぜTDDするのか …?
  • 22. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 一つの答え • 「動作するきれいなコード」のために 「テスト駆動開発入門」
  • 23. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 テストファーストにこだわらない • 表層的に、テストを先に書くかどうかではな く、テストを書くこととプロダクションコー ドを書くことが統合されているか • そして、テストが開発の助けになっているか
  • 24. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 アジェンダ • なぜTDDするのか • どうTDDするか • 技術的な各論 • なぜTDDするのか(again)
  • 25. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 プロジェクト概要 • 大手通信事業者の法人向けサービス開発 • メンバー 開始時11名→現在21名 • 開発プロセスはスクラム • サービスインまでの開発期間7ヶ月
  • 26. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 プロジェクト概要 • Backbone.js(CoffeeScript) + Spring MVC + Spring Batch + Hibernate(JPA) • ユニットテスト総ケース数3800ケース
  • 27. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 立ち上げ時の状況 • クライアントの開発部隊+インテグレーター 2社で1チーム • 初めて顔をあわせるメンバーが多い • とにかく手探り
  • 28. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 ペアプロ • ペアを組んでユニットテストのコーチング • とことんつきあう
  • 29. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 テストファーストにこだわらない • イテレーションの中で実装とテストが完結し ていれば、テストファーストでなくてもよい ことに • テストがあることのメリットを実感してもら う
  • 30. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 ユニットテストを過信しない • フェイルファストしてないユニットテストが、 しているテストと比べて信頼性を欠くのは事 実 • 自動でないテストも重視 • ユニットテストから漏れるバグがあることを 受け入れる
  • 31. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 全部をテストしない 「サーバーサイドはばっちりテストを書きます。 フロントエンドも自動テストして、end to end のテストもSeleniumで自動化します」 「落ち着いてください」
  • 32. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 • まずはサーバサイドのユニットテストの整備 から • サーバーサイドはAPIのエンドポイントとな るController/Serviceクラスについてはテス トを網羅 • 後は必要に応じて
  • 33. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 100点を目指さない。優先順位をつける ユニットテストの5つの規則(F.I.R.S.T) • 再現性がある (Repeatable) • 独立している(Independent) ※ほか、高速である(Fast)/自己検証可能(Self-Validating)/適時性(Timely) 「Clean Code アジャイルソフトウェア達人の技」
  • 34. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 スキル・ノウハウの共有 • スプリントごとにペアプロのペアを組み替え • アトラシアンフルスタック (JIRA/Confluence/Bamboo/Stash)による 情報共有 • 「伝言ゲームソリューション」
  • 35. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 しかし問題も… 開発が進むにつれ、たまっていく技術的負債
  • 36. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 技術的負債 • 意図がはっきりしないテスト • テストメソッド名とやっていることが一致しな いテスト • コピペ • モックの使いすぎ • etc…
  • 37. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 技術的負債の返済 • 改善サイクルをまわす • スプリントごとの振り返り(KPT) • Tryをちゃんとタスク化する、工数を割り振 る
  • 38. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 結果 • リリース判定会議をスムーズにクリア • リリース直前に殆どのメンバーが定時帰り • サービスイン後も定期的にリリースを実施
  • 39. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 どうしてうまくいった? • RESTfulのAPIを定義した上で、フロントエンド とサーバサイドでそれぞれ実装して、それを結 合するというプロセスだったので、ユニットテ ストでサーバーサイドの動作を確認するという アプローチが自然だった • Controller層とService層もModuleを分割してい たので、同じ事が言える
  • 40. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 「信頼で結ばれた共同体」(※) • 「2人目」の存在 • 問題を指摘するとちゃんと次のスプリントに のせてくれる • 人対人でなく、問題対私たち • 「いいもの」をつくるという合意 ※「組織パターン」から
  • 41. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 アジェンダ • なぜTDDするのか • どうTDDするか • 技術的な各論 • なぜTDDするのか(again)
  • 42. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 お品書き • スローテスト • データベースを使うテスト • Controller層のテスト • モック • フロントエンド • End to Endのテスト • 作業をテストする
  • 43. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 スローテスト怖い スローテストによる開発リズムの悪化 →ビルドの通らないコードのpush →CIの信頼性低下 →デリバリーのフロー崩壊
  • 45. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 よくあるスローテスト対策 • 組み込みデータベースを使う • データベースをモックする
  • 46. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 だがちょっとまってほしい • そもそも、「データベースを使うと遅い」の であれば、データベースって業務に使えない です… • 「データベースを使うテストは遅い」は都市 伝説?
  • 47. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 実例(その1)
  • 48. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 実例(その2) https://twitter.com/setoazusa/status/194746629159526400
  • 49. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 • Java開発の場合は、スローテストの原因になる のは、コンテナの立ち上げ • ユニットテストの望ましい姿(独立性)からは外れ ますが、Spring Frameworkの SpringJUnit4ClassRunnnerはContainerの Contextをキャッシュする実装になっているので、 初期化コストはおさえられる。
  • 50. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 何がデータベースを使うテストを難しくするのか • ネックとなるのはテストの実行時間よりも、 テストデータのメンテナンスに必要なコスト が失わせる、テストのリズム感
  • 51. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 Excelを捨てよ、街へ出よう • IDEで作業しているときに一々Excelたちあげ るのたるいし… • Excelでファイルを開いているためにIDEがビ ルドエラーになるのってあるあるですよね? • そもそも分散バージョン管理しているとマー ジできない!
  • 52. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 XMLだけど自動生成すれば問題ないよねっ • 本当はYAMLなりJSONにしたかったのですが、 DBUnitとの相性との関係で。 • テストデータ作成時は開発者のテストデータに 一度投入した後、mavenプラグインでエクス ポートする方法を採用 • ただ、mavenでエクスポートするのはあまり使われ てないみたい..
  • 53. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 データベースのアサーション、どうやろう… • データベースの更新系処理は、データベースの テーブル全体をアサーションするのがセオリー。 • しかし、テストに関係してない、更新されない データまで期待値に含む必要があるため、テス トデータのメンテナンスコストが増大する問題 がある。
  • 54. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 • データベースの更新・削除の前後で、テーブ ルの状態の差分を取り、その差分をアサー ションするようにDBUnitをカスタマイズ。 (デルタアサーション) • このことのより、期待値のデータのメンテナ ンスコストを削減
  • 55. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 データベースマイグレーションはTDDに必須 • 開発者の相互の環境がテスト実行に影響を与 えないようにするため、開発者ごとに Vagrant でデータベースを用意。 • ローカル/CI/開発環境/ステージング/本番の スキーマ構成を管理するため、データベース マイグレーションツールを使用。
  • 56. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 MyBatis Migrationsによるマイグレーション
  • 57. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 Controller層のテストあるある Controller層はユニットテスト書けなくはない けど、ブラウザから叩く時の条件とは違うし、 struts-config.xmlが正しいかは結局Tomcat起 動しないとわからないし… だったらユニットテストいらないじゃん!
  • 58. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 Controller層のテスト • End to Endになるべく近い条件でテストした い • Spring MVC Test Frameworkはhttpのリク エストを高い精度でシミュレートできるため、 これでControllerをテスト
  • 59. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 Spring によるRESTful APIのテスト mockMvc.perform(get("/company/fieldnotes.jp/users/hiroy [email protected]")) .andExpect(jsonPath("$.id",is("[email protected]"))) .andExpect(jsonPath("$.firstName",is("Hiroyuki"))) .andExpect(jsonPath("$.lastName",is("Ohnaka"))) .andExpect(status().isOk());
  • 60. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 モックした場合のコンテナー汚染問題 • Dependency Injectionしたコンポーネント内の オブジェクトをモックした場合、Springのコン テナー内のオブジェクトが汚染される問題 • モックを使うテストケースに@DirtyContextを つければ回避できるが、テストが目に見えて遅 くなるため @After のメソッドの中でオブジェ クトを差し戻すように修正
  • 61. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 フロントエンドのユニットテスト • サーバーサイドのみのテストでもフロントエ ンドに良い効果は及ぼせる • フロントエンドを改修する時に、サーバーサ イドをテストでガードできているため、リグ レッションの検証範囲を限定できる。
  • 62. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 とはいうものの… • 開発が進むにつれ、フロントエンドにテスト がないことよりサーバーサイドとのリズムの ずれが顕在化 • 結合する時のテストの粒度のずれ • リファクタリングのしやすさのずれ • ブランチのマージする時のリスクのずれ
  • 63. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 「安西先生、テストが書きたいです…」
  • 64. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 フロントエンドのテストへの取り組み • mocha でモデルのバリデーションのテスト から、そこから徐々に拡大 • CasperJs + mocha でRestfulのAPIをモッ クした状態での機能テスト
  • 65. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 • もともとGruntでビルドするようにしていた ため、テスティングフレームワークの組み込 み自体は意外にすんなりいった • ただ、テストの書き方は現在も試行錯誤中
  • 66. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 end to end のシステムテスト • リグレッションテストは、イテレーション(1 週間ないし2週間)の最後に、開発メンバー全 員で手動で行うことによって実施 • テストケースはTestLinkで管理
  • 67. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 end to end レベルのシステムテスト • プロジェクト終盤から、Geb+Spockによる 自動リグレッションテストに徐々に移行 • 現在は、自動リグレッションテストと手動リ グレッションテストが共存している状態
  • 68. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 デプロイ自動化の問題 • プロジェクトのミッションとしてDevOpsの 推進があり、その一環として自動デプロイを 実施 • 自動デプロイの実装時に、スクリプトの問題 による不具合・リグレッションが多発
  • 69. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 ServerSpecによるデプロイ作業の検証 ServerSpecでデプロイスクリプトの動作を検証 し、CIサーバーから各環境に対してテストを実 施することで事態を改善
  • 70. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 describe service('jboss') do it { should be_enabled } it { should be_running } end describe command("wget -O - http://localhost:8080/service/status") do it { should return_exit_status 0 } end describe "setting.propetiesがデプロイされていること" do describe command("diff #{RESOURCES}/setting.properties #{JBOSS_HOME}/properties/setting.properties") do it { should return_exit_status 0 } end end
  • 71. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 • サーバー環境に対する操作等の正当性をテス ティングフレームワークで担保するのは、リ ターンを得やすいためおすすめ • 他にも、環境ごとのプロパティファイルの項 目に不整合がないかの検証をCI環境で実施す るなど(RSpecを使用)
  • 72. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 アジェンダ • なぜTDDするのか • どうTDDするか • 技術的な各論 • なぜTDDするのか(again)
  • 73. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka 荒みきったコード 疲弊しきった現場 爆弾処理のような リリース http://www.flickr.com/photos/okinawa-soba/2951808529/ http://www.flickr.com/photos/22719239@N04/2246462044/ http://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:Bomb_neutralizing_EOD_9.jpg
  • 74. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 もうウンザリです。何も改善できません。
  • 75. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 もうウンザリです。何も改善できません。 「しかし、私たちにはプログラミングをする本当の理由 があるはずです。」 「もし、自分や同僚がプログラミングを楽しめるなら、 どんなシステムに取り組んでいるかは重要ではありませ ん。そのシステムに対してきちんとした仕事ができるは ずで、そうでなければ待っているのは落胆です。そう なってしまっては何の楽しみもありませんし、私たちは そんな目に遭うべきではありません。」 「レガシーコード改善ガイド」
  • 76. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 「君が質の高いソフトウェアを届けることは誰 にも止められない。君が現場に立って、お客さ んに向けてプロジェクトの状況と、プロジェク トに必要なことを誠実に伝えることも誰にも止 められないんだ。」 「アジャイルサムライ」
  • 77. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 なぜTDDするのか 私の場合…
  • 78. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 「君にも君を動かしているものがあるでしょう?」 あなたの場合…
  • 79. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 「世界よ 変われ」(※) • ミッションを共有する仲間が集うコミュニ ティで、 • プログラマーが一人一人知恵を持ち寄り、議 論し、勇気づける場が出来たときに、世界は 変わる • そう思う。 ※いきものがかり 「NEW WORLD MUSIC」
  • 80. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 あなたがコミュニティです • キミのいる世界、わたしのいる世界 • 自分が完璧なエンジニアでないことを認める • 問題を他人事にしない。真摯に向き合う
  • 81. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 「信頼で結ばれた共同体」のために • スキルの有無/キャリアの長短を人を計る尺度に しない 「新人だから知らないと思うけど」なんてとんでもない! • IT技術者としてのバックグラウンドを尊重する • ペアの意志決定を尊重する
  • 82. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 この発表での結論 • TDDを導入するのに必要なのは、チームをつ くること。 • チームをつくるということは、コミュニティ をつくるということ。 • そのことに、ウォータフォールもアジャイル も関係ないと思います。
  • 83. #ccc_r11 Copyright 2014 Hiroyuki Ohnaka #ccc_r11 最後に • 自分たちのやっていることがTDDのプラクティ スに沿っているかどうか、そのことはあまり気 にしていないです。 • 答えは、みなさんの現場にあります。 • Have a nice Testing! • ご静聴ありがとうございました。