Japan Symposium on Software Testing 2004

はじめてみようテストファースト
JaSST’04 チュートリアル2
2004年1月28日 10:00~
佐賀大学 大月 美佳 …こと、みかまま
東京コンファレンスセンター 品川
Japan Symposium on Software Testing 2004
おおまかな流れ
• テストファーストとは何か
– テストファーストで何が嬉しいの?
– テスト駆動型開発の流れ
• テストファーストの実際
– xUnitとCppUnit
– CppUnitを使うには
– CppUnitの手順と演習問題
• 質問など(10分)
• 休憩(5分)
• επιστημη(えぴすてーめー)さんにバトンタッチ
2
Japan Symposium on Software Testing 2004
テストファーストとは
• Kent Beck 提唱
eXtreme Programming(XP)のプラクティス(実践項目)のひとつ
XPについては、第3章(p. 89~)を参照
• 単体テストを最初(first)に書く
実装はその後(テストの前には書かない)
• テスト駆動型開発に発展
テストに駆動される形になるため
「テスト駆動開発入門」 ISBN: 4894717115 ケント・ベック
3
Japan Symposium on Software Testing 2004
テストファーストの利点
• バグの早期発見
– テストで押さえられる範囲において(完全ではない)
• 安心度が高まる
– 変更に対する心理的抵抗が下がる
• 実装前にインターフェースの仕様が明確になる
– どのような使われ方をするかから考える
– どのような使われ方がやばいか、も考えるとなお良し
• 楽しい
– 小さな挑戦をリズム良く繰り返せる
• 後でテストを見ると使い方が分かる
– サンプル駆動型、と言っている人も
4
Japan Symposium on Software Testing 2004
テスト駆動開発の流れ
• 詳細は1.3.1項 (p. 24~)
5
Japan Symposium on Software Testing 2004
xUnit
• テスティングフレームワーク
– テストのドライバ→ボトムアップに向いている
– ホワイトボックスというよりはブラックボックス
• Java言語用から各種言語へ
– Junit, CppUnit, CUnit, NUnit, PerlUnit, RubyUnit, …
– 総称してxUnit
6
Japan Symposium on Software Testing 2004
CppUnit
• C++用のテスティングフレームワーク
– 他にもある(CppUnit-x)
– cppunit.sourceforge.net
今更新が停滞中…
7
Japan Symposium on Software Testing 2004
CppUnitを使うには
• C++開発環境
– Visual C++ 6.0
– Borland C++
– GNU C++ (+ make or automake)
• CppUnitインストール
– インストールの詳細は、2.2節(p. 36)
• 環境設定が必要
– Visual C++の環境設定→2.4.2項(p. 80)
– GNU C++ (+ make)での環境設定→2.4.1項(p. 74)
8
Japan Symposium on Software Testing 2004
CppUnitを使ったテスト駆動
9
Japan Symposium on Software Testing 2004
CppUnit基本手順
1. 新しいテスト対象
1.
2.
3.
4.
テスト対象クラスを空で作る(定義のみ)
テストクラスを作る(テンプレート* →5.2.1項 p.239~)
Main部を作る(テンプレート→5.2.2項 p.241~)
動作確認をする
2. テストケースの追加
1.
2.
3.
4.
5.
テスト関数を追加・実装する(ASSERTマクロ一覧*→A.4節 p.275)
テストが失敗することを確認する
テスト対象クラスを実装する
テストが通ることを確認する
リファクタリングする
10
Japan Symposium on Software Testing 2004
基本手順サンプル
• Visual C++ にて実演
11
Japan Symposium on Software Testing 2004
演習1
• CGIを処理するC++プログラムを作成するために、
CGIInput, DataProcesor, HTMLOutputという3つの
クラスを作ることにしました。
– 各クラスのヘッダファイルを作成しましょう
» メンバ変数、関数はない状態で
– 各クラスのテストクラスのヘッダファイルを作成しましょう
» テストの中身はない状態で
– 3つのテストクラスを駆動するTestMain.cppを作成しましょう
– ビルドできるように構成しましょう
» VC++6.0ならばワークスペースを、g++ならばMakefileを
– ビルドして結果を確認しましょう
12
Japan Symposium on Software Testing 2004
演習2
• 演習1で作成した各クラスに以下の関数を実装します。
必要だと思うテストケースを書き出してみてください。
– char *CGIInput::getarg(char *argname)
» CGIの変数名を文字列(argname)で指定すると、その値を文字列で返す
– char *DataProcesor::addition(char *xstr, char *ystr)
» 2つの整数値を文字列(xstr, ystr)で受け取り、その結果を文字列で返す
» 与えられた文字列が数値でない場合はエラーメッセージ(Not Number)を
返す
– void output(char *message, ostream & os)
» 表示したいメッセージを文字列(message)で受け取り、指定された出力スト
リーム(os)にHTMLフォーマットで書き出す。
13
Japan Symposium on Software Testing 2004
テストケースの実装
• テストケースをテストクラスの関数で実装する
– 元来はテストケース=テストクラス
– クラス数が爆発、混乱→アダプタパターンで1クラスに集中
– setUp, tearDownは各テスト関数の実行前と後にそれぞれ実行
アダプタ
この前後
14
Japan Symposium on Software Testing 2004
ASSERTマクロの使い方
• ヘッダ cppunit/TestAssert.h
– 明示的に読み込む必要はあまりない
• Visual C++にて実演
–
–
–
–
–
–
CPPUNIT_ASSERT(条件)
CPPUNIT_ASSERT_MESSAGE(メッセージ, 条件)
CPPUNIT_FAIL(メッセージ)
CPPUNIT_ASSERT_EQUAL(期待した値, 実際の結果)
CPPUNIT_ASSERT_EQUAL(メッセージ, 期待した値, 実際の結果)
CPPUNIT_ASSERT_DOUBLES_EQUAL(期待した値, 実際の結果, 誤
差)
15
Japan Symposium on Software Testing 2004
演習3-1
• 演習2の関数CGIInput::getargについて以下のテス
トを実装してください
– 環境変数REQUEST_METHODに"GET"が、環境変数QUERY_STRING
に"x=12&y=6&submit=submit"が与えられたとき、
CGIInput::getarg("x")が"12"、CGIInput::getarg("y")が"6"、
CGIInput::getarg("submit")が"submit"、という文字列を返すかどうか
チェックするテスト
– 環境変数REQUEST_METHODに"GET"が、環境変数QUERY_STRING
に"x=3&y=102&submit=submit"が与えられたとき、
CGIInput::getarg("x")が"3"、CGIInput::getarg("y")が"102"、
CGIInput::getarg("submit")が"submit"、という文字列を返すかどうか
チェックするテスト
16
Japan Symposium on Software Testing 2004
演習3-2
• 演習2の関数DataProcessor::additionについて以下
のテストを実装してください
–
–
–
–
–
2つの文字列"12", "21"を渡すと、文字列"33"を返すようなテスト
2つの文字列"4", "102"を渡すと、文字列"106"を返すようなテスト
2つの文字列"-6", "10"を渡すと、文字列"4"を返すようなテスト
2つの文字列"3", "-10"を渡すと、文字列"-7"を返すようなテスト
2つの文字列"A", "-10"を渡すと、文字列"Not Number"を返すようなテ
スト
17
Japan Symposium on Software Testing 2004
演習3-3
• 演習2の関数HTMLOutput::outputについて以下の
テストを実装してください
– 文字列"result"が与えられたとき、与えられた出力ストリームに、以下
のような文字列を書き出すテスト
<html><head><title>Result</title></head>
<body><h1>Result: result</h1></body></html>
– 文字列“12”が与えられたとき、与えられた出力ストリームに、以下のよ
うな文字列を書き出すテスト
<html><head><title>Result</title></head>
<body><h1>Result: 12</h1></body></html>
18
Japan Symposium on Software Testing 2004
実装とリファクタリング
•
最初はダミーコードから
– 環境変数QUERY_STRINGに“x=12”でgetarg(“x”)なときに、
char *getarg(char *argname) { return “12”; }
– addition(“1”, “2”)なときに、
char *addition(char *xstr, char *ystr) { return “3”; }
– output(“test”, os)なときに、
void output(char *message, ostream &os) { os << “test”; }
•
重複の削除(リファクタリング)
– コードで重複している部分を置き換えていく
“3” → _itoa(3) → _itoa(1 + 2) → _itoa(atoi(“1”) + atoi(“2”))
→ _itoa(atoi(xstr) +atoi(ystr))
– 面倒くさくても1ステップづつやるのがこつ
– C++の場合メモリ管理が入る
19
Japan Symposium on Software Testing 2004
演習4
• 演習3-1~3-3で実装したテスト関数をクリアするコー
ドを、ダミーコードから1段1段リファクタリングしながら
実装してください
20
Japan Symposium on Software Testing 2004
テストを書けばいいというものではない
• 書かないよりは書いた方がまし
でも、今あるテストでは対処できない例を考えているか?
• テストに関する知識があれば鬼に金棒
– 境界値分析や状態の組み合わせなどの技法
– 開発環境の差異
– 並列環境や分散環境への対応
などなど
• 開発者とテスト技術者との知識交流
があるといいのではないか
21
Japan Symposium on Software Testing 2004
演習5
• 演習3-1~3-3では対処できない例を1つ以上挙げ、
それらに対するテストコードを追加してください。また、
このテストコードをクリアできるコードを実装してくださ
い。
22
Japan Symposium on Software Testing 2004
最後に
• より進んだ利用に向けて
– 自動生成/支援環境
河童プロジェクト
– モックフレームワーク
C++用→MockPP
– GUI特にWeb
HttpUnit,
• 開発者とテスト技術者の交流を
– よりよいソフトウェアを作るために
23
Japan Symposium on Software Testing 2004