プログラマのためのテスト1

45
プログラマのためのテスト Kuniaki IGARASHI [email protected] http://igarashikuniaki.net/tdiary/ 2007.4.16

Upload: kuniaki-igarashi

Post on 24-May-2015

2.042 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: プログラマのためのテスト1

プログラマのためのテスト

Kuniaki [email protected]

http://igarashikuniaki.net/tdiary/2007.4.16

Page 2: プログラマのためのテスト1

私の意見

いいプログラマの条件

コミュニケーション能力と

思いやり

今日、一番言いたいこと!!

Page 3: プログラマのためのテスト1

なんでかというと、

バグの発生しやすいところ人と人との境界

プロジェクトとプロジェクトの境界

そこを埋めるのはコミュニケーション、そしてコードを使う人、読む人への思いやり、

ユーザーさんへの思いやり

そしてバグを無くす技術的手段の1つがテスト

Page 4: プログラマのためのテスト1

目次

テストってなんだろう?

テスト技術のレベル

各種テスト手法

ユニットテスト

自動テスト

Page 5: プログラマのためのテスト1

テストってなんだろう?

IEEE 610.12-1990

ある特定の条件下でシステムまたはコンポー

ネントを操作するプロセスであり、その結果を観察または記録して、システムまたはコンポーネントのある側面を評価すること

IEEE(The Institute of Electrical and Electronics Engineers, Inc.)(アイトリプルイー)アメリカに本部を持つ電気・電子技術の学会。非営利の専門機関。規格策定の有名どころ。ISO (International Organization for Standardization) (アイエスオー、イソ)工業標準の策定を目的とする国際機関。本部はスイス・ジュネーブ。

Page 6: プログラマのためのテスト1

私の意見将来ユーザーに与えるダメージのリスク及び

プログラマの貴重な余暇の時間をバグ対応によって削られるリスクを現実的なレベルまで低減させるための先行投資

テストを行うことは自分のため!

•先行投資なので工数がかかります•でも、投資した以上のリターンを望めます

今日、2番目に言いたいこと!!

実装 社内リリース 検証 納品日

ここで先行投資 ここからの手戻りが少ない終盤ほど時間リソースは貴重

Page 7: プログラマのためのテスト1

つまり!

テストを行うことは自分のため

•デートに行きたいからテストする•飲みに行きたいからテストする•自分の書いたコードに胸を張って

「バッチリです!」と言えるようにテストする

テストはプログラマの義務であり権利

↑今、私が決めました。ええ、決めましたとも。

Page 8: プログラマのためのテスト1

テスト技術のレベル

• レベル1

「テストとデバッグには何の差もない。デバッグ以外にはテストには特別な目的はない」

欠陥は偶然みつかるかもしれないが神頼み

Boris Beizerが提案した5つのレベル

Page 9: プログラマのためのテスト1

テスト技術のレベル• レベル2

「テストの目的は、ソフトウェアが動作することを示すことである」

• レベル3

「テストの目的はソフトウェアが動作しないということを示すことである」

レベル2とレベル3の差は大きい「ある」と思ってモノを探すか、「ない」と思ってモノを探すか。

たとえば、干し草の山から針を探さなければならないとします。あなた方はたぶん、針が1本見つかるまで探すでしょう。

私は、針が全部、見つかるまで探し続けると思います。

アルバート・アインシュタイン

Page 10: プログラマのためのテスト1

テスト技術のレベル

• レベル4

「テストの目的は、何かを証明することではな

く、プログラムが動かないことによって発生する危険性をある許容範囲までに減らすことである」

ソフトウェアの不完全性に関する情報、及び現時点で出荷した場合にどれだけマイナスのインパクトがあるかのリスクを把握し、減少させる。

Page 11: プログラマのためのテスト1

テスト技術のレベル

• レベル5 (最高レベル)

「テストは行動ではない。大げさなテストをすることなく品質の高いソフトウェアを作るための精神的な規律である。」

ポイント:作ったものをテストするのではなく、

テスト容易性を考慮して設計・実装を行う。

今日、3番目に言いたいこと!!

Page 12: プログラマのためのテスト1

テスト手法にもいろいろあります。

どんなテスト手法があるのか見て行きましょう。

Page 13: プログラマのためのテスト1

プログラマ向けの主なテスト手法

UnitTestユニットテスト

DailyAutoTest自動テスト

ManualTest手動テスト

CodeAnalysis静的コード解析

Page 14: プログラマのためのテスト1

メソッド単位でコードを検証するテストコードを書き、

戻り値、副作用が妥当であることを確認するテスト

// テスト対象メソッド addition(int arg1, int arg2) // 引数の和を返し、メンバ変数m_lastResultに結果を格納するメソッド

int result = addition(2,3); // テスト対象のメソッドを実行して

CPPUNIT_ASSERT_EQUAL((int) 5, result); // 結果を確認CPPUNIT_ASSERT_EQUAL((int) 5, m_lastResult); // 結果を確認

UnitTestのCode例

•コード修正時に想定以外の変更が生じても、

ユニットテストが発見してくれる

•閾値に関するUnitTestをしっかり書けば、

バグの出やすい閾値付近でのバグ発生率減少

UnitTestユニットテスト

Page 15: プログラマのためのテスト1

全体結合(または部分結合)し、テスト対象を実行する環境を構築し

毎日テスト実施

メリット•たくさんのテストを回すことができる•毎日実行することでバグが入り込んだタイミングがわかる•実行コストが非常に安価 (PC1台から可)

DailyAutoTest自動テスト

Page 16: プログラマのためのテスト1

人の手による結合テスト万能!自動化をどんなに進めても、手動検証なしでは出荷は不可能

検証エンジニアさんはすごい!報告:動きがカクつきます→絵が1枚落ちていた→ 1/30秒を見切っている

ManualTest手動テスト

Page 17: プログラマのためのテスト1

コード静的解析

• コンパイラワーニングUnitTest実行よりも前にできるテスト

• ソース静的解析ツールFortifyバッファオーバーフロー、メモリリークなどを検出

• コードレビューやはり人の目で見るのは有益

• ペアプログラミング常時コードレビュー隣にぬいぐるみを置いて話しかけるだけでも効果があるそうです。

動的な実行を行わずに静的なコード解析を行うのもテストの一環。

CodeAnalysis

Page 18: プログラマのためのテスト1

テストの種類 まとめ

UnitTest

DailyAutoTest

ManualTest

CodeAnalysis

メソッド単位でコードを検証するテストコード実行時間:10分程度が好ましいルール例:これが通らない場合はコミット禁止

全体結合または部分結合テスト実行時間:9時間以内が好ましいルール例:エラーが出た場合はリリース禁止

人の手による結合テストルール例:致命的なバグが残っていればリリース禁止

静的コード解析ルール例:レビュー実施、リリースまでに解消

Page 19: プログラマのためのテスト1

なぜ多種のテストを使い分けるのか

• テストのカバー範囲

User Operation

UnitTest実際には使用しないメソッドもテスト可能

DailyAutoTest単純だが数をこなせる

ManualTest万能だが工数が限られる

Page 20: プログラマのためのテスト1

なぜ多種のテストを使い分けるのか

• バグ発見までの時間、実行時間の違い

• 検証の品質をあげる

→簡単なバグで検証エンジニアの手を煩わせない

UnitTest

DailyAutoTest

ManualTest

早い

遅い

バグ発見までの時間

短時間

長時間

実行時間

Page 21: プログラマのためのテスト1

バグ発見までの時間

実装 社内リリース 検証 納品日

週1回程度※

繰り返し

実装からの時間

数時間 1日 1週間

UnitTest

DailyTest ManualTest

※但し、ManualTestまでの時間を短くする工夫として、毎日自動でリリース作業も行っています。

このへんでバグがみつかると関係部署に迷惑をかける上、修正後の手動検証も限定的になってしまい危険

出荷後にバグがみつかると最悪、回収で大きな損害さらにユーザー満足度も低下

Page 22: プログラマのためのテスト1

バグを抱えない利点

ゼロ欠陥法(某M$社)

「いかなる場合でも新しいコードを書く前にバグを取り除くことを最優先とする」

理由

• コストバグ修正にとりかかるまでの時間が長くなればなるほど、修正にかかるコストは(時間においても金額においても)高くなる

• スケジュール見積もりバグが存在している場合、スケジュールの見積もりは非常に困難。既存のバグを修正する時間よりも、新機能を実装する時間の方が遙かに見積もりし易い

→リスク見積もりができる

Page 23: プログラマのためのテスト1

ひとやすみ

Page 24: プログラマのためのテスト1

UnitTestのもう少し詳しい説明

Page 25: プログラマのためのテスト1

Test First DevelopmentTest Driven Development本番コードを書く前にユニットテストコードを書く→ テストコードに駆動される開発

テストコードで境界値や全てのケースを網羅しようという意識になる

仕様が固まっていない部分は固めようとする

テスト容易な設計を考慮するようになる

テストを満たすように、突貫コードを書く

仕様破綻がないかチェックする

エラーケースをケアするコードを書く

リファクタリング

Page 26: プログラマのためのテスト1

UnitTestの基礎のさわり

• NGになるケースをまず書こう

テストが実行されていることを確かめましょう

• Mockを使おう下位のモジュールはテスト時には制御可能なMockで置き換え

→時間がかかる処理を置き換えられる

• (可能なら)全てのパターンを網羅しよう(直交表や全ペアといったテスト技法が助けになります)

→参考文献:「はじめて学ぶソフトウェアのテスト技法」

Page 27: プログラマのためのテスト1

UnitTestツール

xUnit•JUnit (JAVA)•NUnit (C#)•CppUnit (C++)

どの環境でもユニットテストツールは大抵あります。

Page 28: プログラマのためのテスト1

UnitTestデザインパターン

どのようなUnitTestを書けばいいのかを形式

化し、テストファーストをプログラマの習慣にすることを目指すwebページ

• web

http://www.marcclifton.com/tabid/87/Default.aspx

現在鋭意翻訳中

http://igarashikuniaki.net/fswiki/wiki.cgi?page=UnitTestPatterns

Page 29: プログラマのためのテスト1

DailyAutoTestのもう少し詳しい説明

Page 30: プログラマのためのテスト1

デイリーテストを必ず実行するための工夫

• CriuseControl.NET

コミット時に自動的にビルド

→ビルドに失敗すればメールでお知らせ

参考文献:http://igarashikuniaki.net/tdiary/20060824.html#p01

※本ドキュメントは概論であるため、↑と重複する部分があります。

Page 31: プログラマのためのテスト1

デイリーテストのメリット

デイリーテストの成果

• お行儀の悪い素材でエラー処理が不適切なのを発見

• 外部製 library 置き換えによる挙動変更に気づく

• 実装した場所とは違う場所への副作用を発見

• 出力ファイルの差分をとることで発覚した不定値問題

• 過去に不具合のあった素材をテストし不具合再発防止

Page 32: プログラマのためのテスト1

例えばこんなデイリーテストはどうでしょう

Page 33: プログラマのためのテスト1

テストの基本はお手本との差分

テスト出力結果 正しい出力結果

差分比較ツール• Fc - Windows 標準コマンドラインツール

• Diff - Unix, Linux

• ExamDiff - Windows GUIツールシェアウェア

Page 34: プログラマのためのテスト1

出力比較テスト

Output Reference

テスト対象

ソースコード

差分比較

Input

以前に出力して問題がないと確信が持てるものをReferenceとして使用

Page 35: プログラマのためのテスト1

ログ比較テスト

ソースコードの要点にログ書き出しを仕込んで置く。変数Dumpや、関数のIn/Outなど。変数の内容や処理経路が異なる場合に発見できる。

下回りのライブラリが置き換えられた場合も、自分たちのコード上を通る経路が変わる場合は違いに気づける。

Output

テスト対象

ソースコード

Reference

Log

お手本

Log

差分比較

Input

Page 36: プログラマのためのテスト1

出力適格判断テスト

Output

テスト対象

ソースコード

出力が規格に適合しているか調べる

規格Checker

規格適合性

チェックツールを

入手または作成

Reference

結果

お手本

結果

差分比較

Input

Page 37: プログラマのためのテスト1

パフォーマンス測定

パフォーマンスを定期的に測ることでパフォーマンス悪化を早期発見、原因把握

Output

テスト対象

ソースコード

出力にかかる時間を測定

グラフ化

→コード履歴をみれば悪化の原因を絞り込める

Input

Page 38: プログラマのためのテスト1

マルチプラットホームテスト

多くのプラットホーム、OSでのテストも自動なら簡単

こんなことを発見できます。

• APIのOS Ver.依存

• WindowsのホームディレクトリなどOS Ver.依存の設定

• アクセス権依存のコード(制限ユーザーで実行など)

• 変数bit量の違いによる不具合

• エンディアネス(リトルエンディアン、ビッグエンディアン)

Page 39: プログラマのためのテスト1

他のテスト

接続過多テスト

バーチャルOSをがんがん起動して一斉に接続

→できなくはないが、毎日回すテストではないかも。

過負荷テスト→CPU使用率を狙って上げてテストこれも毎日回すテストではないかも。

Page 40: プログラマのためのテスト1

テストってばすげー!ここまでのお話で、

テストをやってみようかなとちょっと思ったりしてもらえれば。

テストをやってみたいですよね?

Yes :ぜひ実践してみてください。

No :大人の対応をお願いします。

Page 41: プログラマのためのテスト1

バグによるリスク「史上最悪のソフトウェアバグ」ワースト10を紹介http://hotwired.goo.ne.jp/news/technology/story/20051115301.html

•火星探査機 マリナー1号•旧ソ連のガス・パイプライン•セラック25(放射線治療装置)

•バークレー版UNIX(BSD)のフィンガーデーモンによるバッファー・オーバーフロー•ケルベロスの乱数生成アルゴリズム•米AT&T社のネットワーク停止•インテル社製 Pentium による浮動小数点数の除算ミス•Ping of Death

•アリアン5 フライト501•パナマ国立ガン研究所

(パナマ国立ガン研究所で放射線許容量を誤るバグで死亡者をだした事故で)技師たちは、コンピュータによる計算結果を手作業で再チェックする法的義務を負っていたため、殺人罪で起訴されることになった。

((((;゜Д゜)))ガクガクブルブル

Page 42: プログラマのためのテスト1

まとめ

いいプログラマの条件

• コミュニケーション能力

•思いやり

テストをすることは自分のため

テスト容易な設計・コーディング

Page 43: プログラマのためのテスト1

参考文献

• はじめて学ぶソフトウェアのテスト技法著:リー・コープランド ISBN : 4-8222-8251-1これ1冊でプログラマレベルではテストマスター

• CPPUnitによる実践テスト技法http://www.mikamama.com/CppUnitBook/draft/index.html (draft)

著:大月美佳 ISBN:4-7980-0571-1ユニットテストの入門書。リファレンスとしても便利。

• 知識ゼロから学ぶソフトウェアテスト著:高橋寿一 ISBN:4-7981-0709-3SONYのテストエンジニアさんの著書。実際の経験に基づくノウハウが多数。

Page 44: プログラマのためのテスト1

おしまい

Page 45: プログラマのためのテスト1

テストのゴールはいつだ?

テストにかかった費用+

サポートにかかる費用+

メンテナンスにかかる費用

が最小値になるとき