reloaded
DESCRIPTION
2003/12/04 Talk about Test Driven Development (TDD)TRANSCRIPT
RELOADED
KAZUHIRO FUJIE
ReloadedTest-Driven Development
Kazuhiro FujieItochu techno-science corporation
Follow the white rabbit.
" Have you ever had a dream, Neo, that you were so sure was
real?What if you were unable to wake
from that dream, Neo?How would you know the
difference between the dream world and the real. "
Morpheus
" Welcome to the Desert of the Real! "
Morpheus
Water Fall
• 予測、目録
• 大量のドキュメント
– 変更ができない、実際との乖離
– フィードバックの欠如
• 欠陥、浪費
• プレッシャー、ストレス
• 繰り返す、雪だるま式、混沌
Negative Feedback Loop
Predictability Inventory
Waste Feedback
" I’m sorry, This is the dead end. "
Smith (not Agent)
" Not like this, not like this. "
Switch
Always another way.
Key Maker
Antithesis
• Agile–http://www.agilealliance.com/
• eXtreme Programming–XP–http://www.xprogramming.com/–http://www.xpjug.org/–Test-Driven Development (TDD)
Test-Driven Development
• TDD• テスト駆動開発
• Kent Beck• テスト・ファースト
• シンプル
• 確実な開発手法
Our way or the Highway
Switch
Simplistic Cycle
• Write a test• Make it compile• Make it run• Repeat
簡単なサイクル
• まず、テストコードを書く。
• 次にコードを書く。
• コンパイルする。
• 実行する。
• 繰り返す。
JUnit
• Java言語のテスティングフレームワーク
• Erich Gamma と Kent Beckが開発
• xUnit• ユニットテスト
• Testを自動化
• テストの合否判定がわかりやすい
JUnitでテストをつくろう
• サブクラスを作ってテストを書きます。– junit.framework.TestCase– テストクラス名は、Testで終わる名前にします。
– XxxTest
• メソッド内にテストする内容を書きます。– メソッド名は、testで始まる名前にします。
– testXxx– テストは、Assertクラスのアサーションメソッドを使い
ます。
– junit.framework.Assert
アサーションメソッド
• assertTrue(boolean condition) • assertEquals(Object expected,
Object actual)
JUnit テストのはじめとおわり
• setUp()メソッドで共通なテストの準備
• tearDown()メソッドで共通な後処理を書くこともできます。
– junit.framework.TestCase
• 順番
–setUp() -> テストメソッド -> tearDown()
JUnitの実行
• TestRunner– junit.textui.TestRunner– junit.swingui.TestRunner
public static void main(String[] args) {junit.textui.TestRunner.run(StringConcatenationTest.class);
}
C:¥>java junit.textui.TestRunner StringConcatenationTest
C:¥>java junit.swingui.TestRunner
テキスト・モード
Reload classes every run
" I know Kung Fu. "
Neo
" Show me. "
Morpheus
文字列を繋げる
• 二つの文字列を繋げる。
• テスト・リスト
–1. 二つの文字列が空。
–2. 最初の文字列が空。
–3. 二番目の文字列が空。
–4. 両方とも空ではない。(二つ文字列あり。)
テスト1:二つの文字列が空。
• まずは、このテストコードを書きます。
• assertEquals 二つの値が等しいか?
• まだ、コンパイルはできません。
• 次にコードを書きましょう。
public void testEmpty() {assertEquals("", cat.concatenate("", ""));
}
実装1:二つの文字列が空。
• コンパイルできるようにコードを書きます。
• とりあえず、nullを返すようにしました。
• さあ、コンパイルしてテストしてみましょ。
• どうでしたか?
public String concatenate(String left, String right) {return null;
}
判定1:レッド
再実装1:二つの文字列が空。
• テストは、空文字列を期待しているので、それを返すようにしました。
• さあ、もう一回テストをしましょ。
• 今度は… グリーン?
public String concatenate(String left, String right) {return "";
}
再判定1:グリーン
テスト2:最初の文字列が空。
• 次は、このテストコードを書きます。
• 先ほどの要領で。
• これでテストすると…
public void testLeftEmpty() {assertEquals("abc", cat.concatenate("", "abc"));
}
実装2:最初の文字列が空。
• テストが成功しないので、先ほどの実装をまた変えます。
• 両方のテストが通るようにするには…
• さあどうでしょう?
public String concatenate(String left, String right) {return right;
}
テスト3:二番目の文字列が空。
• ここまでで二つのテストが成功しました。
• 今度は、このテストコードを書きます。
• これでテストするともちろん…
public void testRightEmpty() {assertEquals("abc", cat.concatenate("abc", ""));
}
実装3:二番目の文字列が空。
• 今度はどうしましょう。
• テストを3つとも成功させるには…
public String concatenate(String left, String right) {if ( right.length() == 0) {
return left;}return right;
}
テスト4:両方とも空ではない。
• 最後のテストコードを書きます。
• これで全部で四つのテストを書きました。
public void testNeitherEmpty() {assertEquals("abcdef", cat.concatenate("abc", "def"));
}
実装4:両方とも空ではない。
• すべてのテスト成功させるには…
• グリーン?そしてクリーン?
public String concatenate(String left, String right) {if (right.length() > 0 && left.length() > 0 ) {
return left + right;} else if ( right.length() == 0) {
return left;}return right;
}
実装5:お掃除
• コードが重複しているような気が…• right が空だったら、
– "left" = "left" + "right"
• これもグリーン?そしてクリーン?
public String concatenate(String left, String right) {if (left.length() > 0 ) {
return left + right;}return right;
}
実装6:お掃除の続き
• left が空だったら、
– " right " = "left" + "right"
• これはシンプル!クリーン!
• そして、これもグリーン?
public String concatenate(String left, String right) {return left + right;
}
判定6:グリーン
" Causality, Action, Reaction,
Cause and Effect. "
Merovingian
Real Cycle
• Outline the test we will need• Then
–Write a test–Make it compile–Make it run–Eliminate all duplication–Repeat
" There is a difference between knowing the road
and following it. "
Morpheus
スタック
• スタックを実装する。
• テスト・リスト
–1. 何も入ってないと空である。
–2. 最後に入れたのが最初に出る。
–3. 最初に入れたのが最後に出る。
–4. 3個入れると3個入っている。
スタックのイメージ
• オブジェクトを挿入–push( Object obj )
• オブジェクトを取り出す–pop( )
• スタックが空かどうかを真/偽で返す– isEmpty( )
• スタックのサイズを返す–size( )
スタック (改)
• スタックを実装する。
• テスト・リスト (改編)–1. 何も入ってないと空である。
–2. 1個入れると空ではない。
–3. 1個入れると1個入ってる。
–4. 1個取り出すと空になる。
–5. 最後に入れたのが最初に出る。
–6. 最初に入れたのが最後に出る。
スタック step1
• test
• implementation
public void testEmpty() {assertTrue(stack.isEmpty()); // step 1
}
public boolean isEmpty() {return true; // step 1
}
スタック step2
• test
• implementation
public void testEmpty() {…assertEquals(0, stack.size()); // step 2
}
public int size() {return 0; // step 2
}
スタック step3
• test
• implementation
public void testOneIn() {stack.push(new String("first")); // step 3
}
public void push(Object o) { // step 3}
スタック step4 test
public void testOneIn() {…assertFalse(stack.isEmpty()); // step 4
}
スタック step4 impl.
private boolean empty_ ; // step 4
public Stack() {empty_ = true; // step 4
}
public boolean isEmpty() {return empty_; // step 4
}
public void push(Object o) {empty_ = false; // step 4
}
スタック step5 test
public void testOneIn() {…assertEquals(1, stack.size()); // step 5
}
スタック step5 impl.private List stack_; // step 5
public Stack() {stack_ = new ArrayList(); // step 5
}
public boolean isEmpty() {if ( stack_.size() > 0) { // step 5
return false;}return true;
}
public void push(Object o) {…stack_.add(o); // step 5
}
スタック step6
public void testOneInAndOutEmpty() {stack.push(new String("first"));stack.pop(); // step 6
}
• test
• implementationpublic Object pop() {
return new Object(); // step 6}
スタック step7
• test
• implementation
public void testOneInAndOutEmpty() {…assertTrue(stack.isEmpty()); // step 7
}
public Object pop() {return stack_.remove(size()-1); // step 7
}
スタック step8
public void testLastInFirstOut() {stack.push(new String("first"));stack.push(new String("second"));stack.push(new String("third"));assertEquals("third", stack.pop()); // step 8
}
• test
• Implementation–Remains as it is.
スタック step9
public void testLastInFirstOut() {…assertEquals("second", stack.pop());assertEquals("first", stack.pop()); // step 9
}
• test
• Implementation–Remains as it is.
スタック step10
public boolean isEmpty() {return stack_.isEmpty(); // step 10
}
• clean
スタック step excessivepublic void testLastInFirstOutAndFirstInLastOut () {
assertTrue(stack.isEmpty());assertEquals(0, stack.size());stack.push(new String("first"));assertFalse(stack.isEmpty());assertEquals(1, stack.size());stack.push(new String("second"));assertEquals(2, stack.size());stack.push(new String("third"));assertEquals(3, stack.size());assertEquals("third", stack.pop());assertEquals(2, stack.size());assertEquals("second", stack.pop());assertEquals(1, stack.size());assertEquals("first", stack.pop());assertEquals(0, stack.size());assertTrue(stack.isEmpty());
}
" However, I was again frustrated by failure. "
The Architect
" Denial is the most predictable of all human
response. "
The Architect
" To deny our own impulses is to deny the
very things that makes us human. "
Mouse
" Green and Clean! "
Kent Beck
リファクタリング
• Martin Fowler• 改善すること
• 「実装したあとで、設計を改善する」
• できるだけシンプルに
• 重複を取り除く
• 修正前と後では同じ動作
• テストで確認
XPでのテスト/コードサイクル
• テストを一つ書く。
• テストをコンパイルする。テストを呼び出すコードをまだ実装していないのでコンパイルに失敗する。
• コンパイルに必要なだけの実装を行う。– (必要なら最初にリファクタリングを行う)。
• テストを実行し、失敗するのを確認する。
• テストをパスするのに必要なだけの実装をする。
• テストを実行し、パスするのを確認する。
• リファクタリングを行い重複している部分を取り除く。
• 最初から繰り返す。
まとめ
• 少しずつ作っていく。
• 確認しながら作っていく。
• Green and Clean!• シンプルにする。
• 不安からの開放。
• テストを楽しく。
" Cause and Effect,My Love. "
Persephone
" Dejavu? "
Neo
JUnit Basics
• サブクラスを作ってテストを書きます。
– junit.framework.TestCase
• クラス名は、Testで終わる名前
• メソッド名は、testで始まる名前
• setUp()メソッドでテストの準備
• tearDown()メソッドでテストの後処理
アサーションメソッド
• assertTrue(boolean condition) • assertFalse(boolean condition) • assertEquals(Object expected,
Object actual) • assertSame(Object expected,
Object actual)
アサーションメソッド 続き
• assertNotSame(Object expected, Object actual)
• assertNull(Object object) • assertNotNull(Object object)• fail()
TestCase and TestSuite
" Touch me and that hand will never touch anything
again. "
Trinity
Eclipse
• IDE– Integrated Development Environment– 統合開発環境
– Javaの開発も可能
• オープンソースプロジェクト– eclipse.org– 当初IBMにより開発
• プラグインにより拡張– 様々なプラグインが公開されている
Eclipse で JUnit
• JUnit プラグイン が組み込まれています。
• Ctrl + S– セーブとコンパイル
• Ctrl + F11– 前回の実行。
Ant
• ビルド・ツール–UNIXでの"make"ツールみたいなもの
• Java-based–Ant自身がJavaでできている
– Java開発環境での必須標準ビルドツール
– 標準でいくつかのタスクが用意されている
– 拡張も可能
• build.xml
Eclipse で Ant
• ビルドファイルの作成、実行がきます。
CVS
• Concurrent Versions System• バージョン管理ツール
–UNIXでの"SCCS"や"RCS"みたいなもの
• ファイルのリポジトリ(保管場所)
• サーバー・クライアントで使える。
–WinCVS, TortoiseCVS, …
• チームでの開発に特に有効
WinCVS
TortoiseCVS
Eclipse で CVS
• CVSのクライアントを組み込んでいます。
" How many people keep silver bullets in their gun? "
Persephone
Maven
• メイベン
• ビルドツール
• プロジェクト管理ツール
• プロジェクト・オブジェクト・モデル (POM)• 現在、ベータ版
Subversion
• バージョン管理ツール
• WebDAV のバージョニング実装
–Web-based Distributed Authoring and Versioning
• サーバー・クライアントで使える
–TortoiseSVN, RapidSVN, …
• 現在絶賛開発中らしい
TortoiseSVN
RapidSVN
XDoclet
• コード生成エンジン
• アトリビュート指向のプログラミング
• Javadoc Doclet として実装
–@タグを使う
• Antなどと連携可能
" More … "
Smith (one of many inside)
Bibliography
• Rebirth –Kent Beck– http://www.tech-arts.co.jp/xp/Rebirth.pdf
• Test-Driven Development–Kent Beck–TDD Training text [2002/09/11-12]– http://www.tech-arts.co.jp/training/topics.html– 但し、テキストは公開されていないようです。
Bibliography
• テスト駆動開発入門
– ケント ベック (著), Kent Beck (原著), 長瀬 嘉秀 (翻訳), テクノロジックアート (翻訳)
– ISBN: 4894717115
Bibliography
• JavaによるExtreme Programmingクックブック アジャイル開発のためのレシピ集
– エリック・M. バーク (著), ブライアン・M. コイナー (著), Eric M. Burke (原著), Brian M. Coyner (原著), 長瀬 嘉秀 (翻訳), テクノロジックアート (翻訳)
– ISBN: 4873111579
Resources
• http://www.junit.org/• http://www.eclipse.org/• http://ant.apache.org/• http://www.cvshome.org/• http://www.wincvs.org/• http://www.tortoisecvs.org/• http://maven.apache.org/• http://subversion.tigris.org/• http://rapidsvn.tigris.org/• http://xdoclet.sourceforge.net/• http://www.xprogramming.com/software.htm
Philosophy
• http://www.agilealliance.com/• http://www.xprogramming.com/• http://www.xpjug.org/xpjug_root/xp.html• http://www.tech-arts.co.jp/xp/xp.html• http://www-
6.ibm.com/jp/developerworks/java/030926/j_j-beck.html
• http://junit.sourceforge.net/doc/testinfected/testing.htm
Philosophy cont.
• http://objectclub.esm.co.jp/eXtremeProgramming/index.html
• http://whatisthematrix.warnerbros.com/rl_cmp/phi.html
• http://awesomehouse.com/matrix/reflect.html#Rebirth
" But I can only show you the door, you have to walk
through it. "
Morpheus
TO BE CONCLUDED.