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

2,521 views

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,521
On SlideShare
0
From Embeds
0
Number of Embeds
23
Actions
Shares
0
Downloads
21
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

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

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

×