プログラマのためのテスト1
TRANSCRIPT
私の意見
いいプログラマの条件
コミュニケーション能力と
思いやり
今日、一番言いたいこと!!
なんでかというと、
バグの発生しやすいところ人と人との境界
プロジェクトとプロジェクトの境界
そこを埋めるのはコミュニケーション、そしてコードを使う人、読む人への思いやり、
ユーザーさんへの思いやり
そしてバグを無くす技術的手段の1つがテスト
目次
テストってなんだろう?
テスト技術のレベル
各種テスト手法
ユニットテスト
自動テスト
テストってなんだろう?
IEEE 610.12-1990
ある特定の条件下でシステムまたはコンポー
ネントを操作するプロセスであり、その結果を観察または記録して、システムまたはコンポーネントのある側面を評価すること
IEEE(The Institute of Electrical and Electronics Engineers, Inc.)(アイトリプルイー)アメリカに本部を持つ電気・電子技術の学会。非営利の専門機関。規格策定の有名どころ。ISO (International Organization for Standardization) (アイエスオー、イソ)工業標準の策定を目的とする国際機関。本部はスイス・ジュネーブ。
私の意見将来ユーザーに与えるダメージのリスク及び
プログラマの貴重な余暇の時間をバグ対応によって削られるリスクを現実的なレベルまで低減させるための先行投資
テストを行うことは自分のため!
•先行投資なので工数がかかります•でも、投資した以上のリターンを望めます
今日、2番目に言いたいこと!!
実装 社内リリース 検証 納品日
ここで先行投資 ここからの手戻りが少ない終盤ほど時間リソースは貴重
つまり!
テストを行うことは自分のため
•デートに行きたいからテストする•飲みに行きたいからテストする•自分の書いたコードに胸を張って
「バッチリです!」と言えるようにテストする
テストはプログラマの義務であり権利
↑今、私が決めました。ええ、決めましたとも。
テスト技術のレベル
• レベル1
「テストとデバッグには何の差もない。デバッグ以外にはテストには特別な目的はない」
欠陥は偶然みつかるかもしれないが神頼み
Boris Beizerが提案した5つのレベル
テスト技術のレベル• レベル2
「テストの目的は、ソフトウェアが動作することを示すことである」
• レベル3
「テストの目的はソフトウェアが動作しないということを示すことである」
レベル2とレベル3の差は大きい「ある」と思ってモノを探すか、「ない」と思ってモノを探すか。
たとえば、干し草の山から針を探さなければならないとします。あなた方はたぶん、針が1本見つかるまで探すでしょう。
私は、針が全部、見つかるまで探し続けると思います。
アルバート・アインシュタイン
テスト技術のレベル
• レベル4
「テストの目的は、何かを証明することではな
く、プログラムが動かないことによって発生する危険性をある許容範囲までに減らすことである」
ソフトウェアの不完全性に関する情報、及び現時点で出荷した場合にどれだけマイナスのインパクトがあるかのリスクを把握し、減少させる。
テスト技術のレベル
• レベル5 (最高レベル)
「テストは行動ではない。大げさなテストをすることなく品質の高いソフトウェアを作るための精神的な規律である。」
ポイント:作ったものをテストするのではなく、
テスト容易性を考慮して設計・実装を行う。
今日、3番目に言いたいこと!!
テスト手法にもいろいろあります。
どんなテスト手法があるのか見て行きましょう。
プログラマ向けの主なテスト手法
UnitTestユニットテスト
DailyAutoTest自動テスト
ManualTest手動テスト
CodeAnalysis静的コード解析
メソッド単位でコードを検証するテストコードを書き、
戻り値、副作用が妥当であることを確認するテスト
// テスト対象メソッド 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ユニットテスト
全体結合(または部分結合)し、テスト対象を実行する環境を構築し
毎日テスト実施
メリット•たくさんのテストを回すことができる•毎日実行することでバグが入り込んだタイミングがわかる•実行コストが非常に安価 (PC1台から可)
DailyAutoTest自動テスト
人の手による結合テスト万能!自動化をどんなに進めても、手動検証なしでは出荷は不可能
検証エンジニアさんはすごい!報告:動きがカクつきます→絵が1枚落ちていた→ 1/30秒を見切っている
ManualTest手動テスト
コード静的解析
• コンパイラワーニングUnitTest実行よりも前にできるテスト
• ソース静的解析ツールFortifyバッファオーバーフロー、メモリリークなどを検出
• コードレビューやはり人の目で見るのは有益
• ペアプログラミング常時コードレビュー隣にぬいぐるみを置いて話しかけるだけでも効果があるそうです。
動的な実行を行わずに静的なコード解析を行うのもテストの一環。
CodeAnalysis
テストの種類 まとめ
UnitTest
DailyAutoTest
ManualTest
CodeAnalysis
メソッド単位でコードを検証するテストコード実行時間:10分程度が好ましいルール例:これが通らない場合はコミット禁止
全体結合または部分結合テスト実行時間:9時間以内が好ましいルール例:エラーが出た場合はリリース禁止
人の手による結合テストルール例:致命的なバグが残っていればリリース禁止
静的コード解析ルール例:レビュー実施、リリースまでに解消
なぜ多種のテストを使い分けるのか
• テストのカバー範囲
User Operation
UnitTest実際には使用しないメソッドもテスト可能
DailyAutoTest単純だが数をこなせる
ManualTest万能だが工数が限られる
なぜ多種のテストを使い分けるのか
• バグ発見までの時間、実行時間の違い
• 検証の品質をあげる
→簡単なバグで検証エンジニアの手を煩わせない
UnitTest
DailyAutoTest
ManualTest
早い
遅い
バグ発見までの時間
短時間
長時間
実行時間
バグ発見までの時間
実装 社内リリース 検証 納品日
週1回程度※
繰り返し
実装からの時間
数時間 1日 1週間
UnitTest
DailyTest ManualTest
※但し、ManualTestまでの時間を短くする工夫として、毎日自動でリリース作業も行っています。
このへんでバグがみつかると関係部署に迷惑をかける上、修正後の手動検証も限定的になってしまい危険
出荷後にバグがみつかると最悪、回収で大きな損害さらにユーザー満足度も低下
バグを抱えない利点
ゼロ欠陥法(某M$社)
「いかなる場合でも新しいコードを書く前にバグを取り除くことを最優先とする」
理由
• コストバグ修正にとりかかるまでの時間が長くなればなるほど、修正にかかるコストは(時間においても金額においても)高くなる
• スケジュール見積もりバグが存在している場合、スケジュールの見積もりは非常に困難。既存のバグを修正する時間よりも、新機能を実装する時間の方が遙かに見積もりし易い
→リスク見積もりができる
ひとやすみ
UnitTestのもう少し詳しい説明
Test First DevelopmentTest Driven Development本番コードを書く前にユニットテストコードを書く→ テストコードに駆動される開発
テストコードで境界値や全てのケースを網羅しようという意識になる
仕様が固まっていない部分は固めようとする
テスト容易な設計を考慮するようになる
テストを満たすように、突貫コードを書く
仕様破綻がないかチェックする
エラーケースをケアするコードを書く
リファクタリング
UnitTestの基礎のさわり
• NGになるケースをまず書こう
テストが実行されていることを確かめましょう
• Mockを使おう下位のモジュールはテスト時には制御可能なMockで置き換え
→時間がかかる処理を置き換えられる
• (可能なら)全てのパターンを網羅しよう(直交表や全ペアといったテスト技法が助けになります)
→参考文献:「はじめて学ぶソフトウェアのテスト技法」
UnitTestツール
xUnit•JUnit (JAVA)•NUnit (C#)•CppUnit (C++)
どの環境でもユニットテストツールは大抵あります。
UnitTestデザインパターン
どのようなUnitTestを書けばいいのかを形式
化し、テストファーストをプログラマの習慣にすることを目指すwebページ
• web
http://www.marcclifton.com/tabid/87/Default.aspx
現在鋭意翻訳中
http://igarashikuniaki.net/fswiki/wiki.cgi?page=UnitTestPatterns
DailyAutoTestのもう少し詳しい説明
デイリーテストを必ず実行するための工夫
• CriuseControl.NET
コミット時に自動的にビルド
→ビルドに失敗すればメールでお知らせ
参考文献:http://igarashikuniaki.net/tdiary/20060824.html#p01
※本ドキュメントは概論であるため、↑と重複する部分があります。
デイリーテストのメリット
デイリーテストの成果
• お行儀の悪い素材でエラー処理が不適切なのを発見
• 外部製 library 置き換えによる挙動変更に気づく
• 実装した場所とは違う場所への副作用を発見
• 出力ファイルの差分をとることで発覚した不定値問題
• 過去に不具合のあった素材をテストし不具合再発防止
例えばこんなデイリーテストはどうでしょう
テストの基本はお手本との差分
テスト出力結果 正しい出力結果
差分比較ツール• Fc - Windows 標準コマンドラインツール
• Diff - Unix, Linux
• ExamDiff - Windows GUIツールシェアウェア
出力比較テスト
Output Reference
テスト対象
ソースコード
差分比較
Input
以前に出力して問題がないと確信が持てるものをReferenceとして使用
ログ比較テスト
ソースコードの要点にログ書き出しを仕込んで置く。変数Dumpや、関数のIn/Outなど。変数の内容や処理経路が異なる場合に発見できる。
下回りのライブラリが置き換えられた場合も、自分たちのコード上を通る経路が変わる場合は違いに気づける。
Output
テスト対象
ソースコード
Reference
Log
お手本
Log
差分比較
Input
出力適格判断テスト
Output
テスト対象
ソースコード
出力が規格に適合しているか調べる
規格Checker
規格適合性
チェックツールを
入手または作成
Reference
結果
お手本
結果
差分比較
Input
パフォーマンス測定
パフォーマンスを定期的に測ることでパフォーマンス悪化を早期発見、原因把握
Output
テスト対象
ソースコード
出力にかかる時間を測定
グラフ化
→コード履歴をみれば悪化の原因を絞り込める
Input
マルチプラットホームテスト
多くのプラットホーム、OSでのテストも自動なら簡単
こんなことを発見できます。
• APIのOS Ver.依存
• WindowsのホームディレクトリなどOS Ver.依存の設定
• アクセス権依存のコード(制限ユーザーで実行など)
• 変数bit量の違いによる不具合
• エンディアネス(リトルエンディアン、ビッグエンディアン)
他のテスト
接続過多テスト
バーチャルOSをがんがん起動して一斉に接続
→できなくはないが、毎日回すテストではないかも。
過負荷テスト→CPU使用率を狙って上げてテストこれも毎日回すテストではないかも。
テストってばすげー!ここまでのお話で、
テストをやってみようかなとちょっと思ったりしてもらえれば。
テストをやってみたいですよね?
Yes :ぜひ実践してみてください。
No :大人の対応をお願いします。
バグによるリスク「史上最悪のソフトウェアバグ」ワースト10を紹介http://hotwired.goo.ne.jp/news/technology/story/20051115301.html
•火星探査機 マリナー1号•旧ソ連のガス・パイプライン•セラック25(放射線治療装置)
•バークレー版UNIX(BSD)のフィンガーデーモンによるバッファー・オーバーフロー•ケルベロスの乱数生成アルゴリズム•米AT&T社のネットワーク停止•インテル社製 Pentium による浮動小数点数の除算ミス•Ping of Death
•アリアン5 フライト501•パナマ国立ガン研究所
(パナマ国立ガン研究所で放射線許容量を誤るバグで死亡者をだした事故で)技師たちは、コンピュータによる計算結果を手作業で再チェックする法的義務を負っていたため、殺人罪で起訴されることになった。
((((;゜Д゜)))ガクガクブルブル
まとめ
いいプログラマの条件
• コミュニケーション能力
•思いやり
テストをすることは自分のため
テスト容易な設計・コーディング
参考文献
• はじめて学ぶソフトウェアのテスト技法著:リー・コープランド 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のテストエンジニアさんの著書。実際の経験に基づくノウハウが多数。
おしまい
テストのゴールはいつだ?
テストにかかった費用+
サポートにかかる費用+
メンテナンスにかかる費用
が最小値になるとき