レガシーコードでtdd力を高めよう #agilesamurai

30
レガシーコードで TDD力を高めよう!! Agile Samurai Base Camp Re:TDD 2014/4/20

Upload: poohsunny-yotaro-takahashi

Post on 24-May-2015

2.355 views

Category:

Documents


2 download

DESCRIPTION

Agile Samurai Base Camp 2013.12.08(Sun) で事例発表した際の資料です。

TRANSCRIPT

Page 1: レガシーコードでTDD力を高めよう #agilesamurai

レガシーコードでTDD力を高めよう!!

Agile Samurai Base Camp Re:TDD 2014/4/20

Page 2: レガシーコードでTDD力を高めよう #agilesamurai

@PoohSunny

● 海外チームと新サービスの立ち上

げに奮闘中。

● 『レガシーコード改善ガイド』が座

右の書

● 「テストがないコードはレガシー

コードだぁっ!!」ってのがちょっ

と前まで口癖

Page 3: レガシーコードでTDD力を高めよう #agilesamurai

はじめに

今日一日おつかれさまー!

Page 4: レガシーコードでTDD力を高めよう #agilesamurai

挙手!

今日TDDを体感してみて

「明日からTDDやってみたいなー」

って思った人!

Page 5: レガシーコードでTDD力を高めよう #agilesamurai

挙手!

今日TDDを体感してみて

「明日から現場でTDDできそうだ!」

って思った人!

Page 6: レガシーコードでTDD力を高めよう #agilesamurai

実践できる?

現場でいきなり

使うのは

なかなか難しい

なんで?

Page 7: レガシーコードでTDD力を高めよう #agilesamurai
Page 8: レガシーコードでTDD力を高めよう #agilesamurai

レガシーコード

● 一部の変更が全てに影響○ ジェンガ / スパゲッティ○ 動いているコードに触るな!○ Edit & Pray(変更して祈る)

● テストが書きにくい構造○ 実践しようにも...

Page 9: レガシーコードでTDD力を高めよう #agilesamurai

このままではイベントの目的が...

テスト駆動開発はソフトウェアの質を確

実に向上させ、日々の成果に直結し

ています。これもエンジニアひとりから

明日から始めることができます。

Agile Samurai Base CampのHP

Page 10: レガシーコードでTDD力を高めよう #agilesamurai

というわけで今日は

レガシーコードでもTDDの実践するにはどうしたらいいのか、

という最初の一歩の話しまーす

(経験談)。

Page 11: レガシーコードでTDD力を高めよう #agilesamurai

今日の話の対象

✕ レガシーコードをTDDで改善しよう

○ レガシーコードで自分のTDD力高めよう

○ 実現までの時間が結構かか

る○ 仲間が必要

○ 「TDDから」が最適解とは限り

ません

Page 12: レガシーコードでTDD力を高めよう #agilesamurai

レガシーコードって?

Page 13: レガシーコードでTDD力を高めよう #agilesamurai

私の出会ったレガシーコード

● これはEclipseの画面の右端です。

● 行数を想像してみてください○ Javaです。○ ざっと数万行です(てへぺろ)

● 青→とある変数にカーソルを当ててみた○ 長寿の変数

Page 14: レガシーコードでTDD力を高めよう #agilesamurai

私の出会ったレガシーコード(フィクションです)

public void legacyMethod(boolean flag1, boolean flag2, HttpServletRequest request){

String code = (String) request.getAttribute("code"); String action = (String) request.getAttribute("action"); List<TargetData> datas = new TargetDataDAO().getTargetData(code); if (action == "1") { if (datas != null && datas.size() != 0) { for (TargetData data : datas) { if ((data.getId() != null && !data.getName() == "") || data.getId == null) { request.setAttribute("data", data); } }

引数が多い!

DBアクセスが近い

ワイド画面でも足りないifネスト

継ぎ足しされた秘伝のif条件

Page 15: レガシーコードでTDD力を高めよう #agilesamurai

一体どうTDDしろと...

● どこからテスト書く?● いつテスト書く?● テストが先かリファクタが先か問題

○ テストがしやすいように内部構造を変える

Page 16: レガシーコードでTDD力を高めよう #agilesamurai

私が(当時)考えたこと

● テスト書こうとしてバグるのはダメ!○ モチベーション下がる○ 変更が怖くなる○ 痛みを伴うのはしんどい!

● まずは小さいところから○ 大胆な構造改革は仲間が増えてからやろう

● 美味しそうなところをやる

Page 17: レガシーコードでTDD力を高めよう #agilesamurai

オススメパターン

不具合に

テストを書いて

立ち向かう

和田 卓人

Page 18: レガシーコードでTDD力を高めよう #agilesamurai

手順(引用)

1. 手元で不具合を再現させる。2. コードを注意深く調べ、不具合を発生させている

最小の部分を絞り込む。3. 最小レベルで不具合を再現させ、不具合が修

正されたら通るような自動テストコードを書く。4. 3.で書いたテストコードを実行し、落ちることを確

認する。

Page 19: レガシーコードでTDD力を高めよう #agilesamurai

手順(引用)

5. 不具合を修正する。

6. 3で書いたテストコードが通ることを確認する。

7.既存の全てのテストを実行し、不具合修正が他の部分を壊していないことを確認する。

Page 20: レガシーコードでTDD力を高めよう #agilesamurai

手順(対レガシーコード)

1. 手元で不具合を再現させる2. コードを注意深く調べ、不具合を発生させている

最小の部分を絞り込む3. 最小部分をくくりだす。4. くくりだした部分にテストを書く。5. テストを書いたところをリファクタリングする。6. 最小レベルで不具合を再現させ、~以下同じ

Page 21: レガシーコードでTDD力を高めよう #agilesamurai

TDDしたい箇所をくくりだす。

● スプラウトメソッド、とか呼ばれる手法○ メソッドの抽出リファクタを実行してみる○ そこにテストを書く

Page 22: レガシーコードでTDD力を高めよう #agilesamurai

最初はif条件文にやるとやりやすい

if ((data.getId() != null && !data.getName() == "") || data.getId == null) {

if (shouldSetAttribute(data)) {(略)

public void shouldSetAttribute(TargetData data){ return (data.getId() != null && !data.getName() == "") || data.getId == null;}

Page 23: レガシーコードでTDD力を高めよう #agilesamurai

テストを書いてリファクタリング

if (shouldSetAttribute(data)) {

public void shouldSetAttribute(TargetData data){ return (data.getId() != null && !data.getName() == "") || data.getId == null;}

public void shouldSetAttribute(TargetData data){ if (data.getId == null) return true; return !"".equals(data.getName())}

Page 24: レガシーコードでTDD力を高めよう #agilesamurai

効果

● 多くのフィードバックを得られる○ 名付けはメソッド名は適切?○ もっとテストしやすい引数にできない?○ もっと読みやすくできない?

● バグったところはまたバグりやすい○ 「あなたのこのまえの修正、デグレ起こしてるっぽ

いですよ(ドヤッ)」

Page 25: レガシーコードでTDD力を高めよう #agilesamurai

悩ましいポイント

● 大きいメソッドだと難しい○ 本当に不安な部分にテコ入れできない

● モチベーション管理が難しい○ 誰かが地雷を踏むまでは一定時間かかる○ それまで効果があるのかが見えにくい

Page 26: レガシーコードでTDD力を高めよう #agilesamurai

対策:もっと大くくりでテストできない?

● DBアクセスがいっぱいあってしんどい?

=> DBアクセスしてテストしてみたら?

● 画面からの情報が多くてしんどい?

=> 画面の自動テストしてみたら?

Page 27: レガシーコードでTDD力を高めよう #agilesamurai

結果

● 頑張ればテストは書ける!状態○ 安心・健康○ 仲間が増える(社内)○ より大きな構造改革

● スキルアップ○ 知らないことをもっと知りたい!という好循環○ 仲間が増える(社外)

Page 28: レガシーコードでTDD力を高めよう #agilesamurai

まとめ(言いたかったこと)

● レガシーコードでも、工夫次第でTDDできるよ!

● もし悩みがあれば、みんなで共有しよう!

Page 29: レガシーコードでTDD力を高めよう #agilesamurai

駆け足すぎた?

質問お待ちしてます!(もっと突っ込んで話したいこともあったし、質問してもらえるとそういうのにも答えられたりするかと。)

Page 30: レガシーコードでTDD力を高めよう #agilesamurai

みんな無理せずレガシーコード改善やろうぜ!

おしまい。質問お待ちしていますー!