• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
ガイオプライベートセミナー2012秋(坂本)
 

ガイオプライベートセミナー2012秋(坂本)

on

  • 725 views

ガイオプライベートセミナー2012秋にて公演したスライドです。

ガイオプライベートセミナー2012秋にて公演したスライドです。
http://www.gaio.co.jp/event/special/gps2012au.html

Statistics

Views

Total Views
725
Views on SlideShare
725
Embed Views
0

Actions

Likes
0
Downloads
1
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    ガイオプライベートセミナー2012秋(坂本) ガイオプライベートセミナー2012秋(坂本) Presentation Transcript

    • ガイオ プライベートセミナー 2012秋 2012年11月2日早稲田大学 情報理工学研究科 坂本 一憲
    • 目次1. 複数言語対応カバレッジ測定環境 – OpenCodeCoverageFrameworkのガイオ・テク ノロジー社単体テストツールへの組み込み事例2. Fault localization – テストカバレッジ研究の最新動向その13. テストオラクルの評価指標 – テストカバレッジ研究の最新動向その24. Test case minimization – テストカバレッジ研究の最新動向その32012/11/2 ガイオ プライベートセミナー 2012秋 2
    • OpenCodeCoverageFrameworkとガイオ・テクノロジー社単体テストツールへの組み込み事例2012/11/2 ガイオ プライベートセミナー 2012秋 3
    • 背景:テストカバレッジ • ソフトウェアテストにおける重要な指標 テストは欠陥の • 多様なテストカバレッジの種類 発見行為 – 命令網羅、分岐網羅など テストケース01: int func(int a, int b) { 開始 a = 1, b= 002: if (a == 0) { a = 2, b= 1 No 命令網羅率03: puts("a == 0"); a == 004: } 80% Yes05: puts(“a == 0”)06: if (b == 0) {07: puts("b == 0"); No b == 009: } Yes09: else { puts(“b == 0”) puts(“b != 0”)10: puts("b != 0");11: }12: } 終了 2012/11/2 ガイオ プライベートセミナー 2012秋 4
    • 既存カバレッジ測定ツールの問題点1. 高い開発コスト:新言語に対応したツールの開発が困難 • 新言語:Scala, Xtend, Go やレガシー言語:COBOL, Fortran への対応2. 統一性の欠如:複数言語での測定が困難 • サーバクライアントモデルのアプリケーション(例:Python + Java)で測定 • Python用、Java用測定ツールの両方が必要、ツール間の相違点によるズレ3. 柔軟性の欠如:カスタマイズが困難 • ライブラリ呼び出しのみを対象とした特殊な網羅率の測定4. 不完全な測定:デッドコードを測定対象にできない • if (false) { System.out.println(“this is dead code.”); } オープンソース化 してGoogle Code テストカバレッジ測定フレームワーク にて公開中 OpenCodeCoverageFramework(OCCF) ツール開発者の支援 ツール利用者の恩恵 2012/11/2 ガイオ プライベートセミナー 2012秋 5
    • 問題と解決:コストと統一性• 開発と保守コストが大きい • フレームワークによる支援 – 新言語への対応が困難 – 共通処理の再利用• カバレッジ種類数がばらばら – 対応カバレッジの統一 – 複数言語での測定が困難 – 柔軟な機能拡張 – 例)Server-Client型 • 新しいカバレッジを追加可能 アプリケーション Java言語 新カバレッジ(Cobertura) Java言語 命令網羅 C言語(COVTOOL) OCCF 分岐網羅 C言語Python言語 フレームワー(Statement クCoverage) 条件網羅 Python言語 共通処理 命令網羅 分岐網羅 条件網羅 条件分岐網羅 2012/11/2 ガイオ プライベートセミナー 2012秋 6
    • 問題と解決:柔軟な測定• 例)ライブラリ呼び出し • 機能拡張による実現 のみを測定対象 – 測定対象の限定• 例)特定変数を測定対象 全ステートメン libfuncのみを対象 変数bのみを対象 トが測定対象 int main() { int main() { int a = 0, b = 1; int a = 0, b = 1; a = libfunc(a); a = libfunc(a); b = func1(a + b); b = func1(a + b); a = libfunc(b); a = libfunc(b); b = func2(a - b); b = func2(a – b); } }2012/11/2 ガイオ プライベートセミナー 2012秋 7
    • 問題と解決:完全な測定 実装が困難• 従来の測定方法 測定もれ問題 – 測定可能な実行処理系の実装 – バイナリコードに測定用コードの埋め込み public class DeadCode { public static void main(String[] args) { System.out.println("main"); 測定不可能 if (false) System.out.println("dead code"); } •実装が簡単 } •測定もれなし• 提案手法 – ソースコードに測定用コードの埋め込み2012/11/2 ガイオ プライベートセミナー 2012秋 8
    • • 自動的に挿入 • カバレッジ情報の出力 OCCFの測定アプローチ • 副作用なし • 測定もれなし 命令網羅と int func(int a) { 分岐網羅を測定 if (a == 0) { int func(int a) { printf("a == 0"); if (branch(0, a == 0)) { } stmt(0); else if (false) { printf("a == 0"); printf("a != 0"); } } AST上で埋め込み else if (branch(1,false)){ } stmt(1); Function printf("a != 0");int func(int a) } } Statement Statement void stmt(int id) { Statement Statement RECORD_STATEMENT(id); printf("a == 0") printf("a != 0") stmt (0) } 抽象構文木(AST) stmt (1) 2012/11/2 ガイオ プライベートセミナー 2012秋 9
    • OCCFで測定可能な言語測定可能 (メ ジャー)• 測定可能:測定対象が存在 手続き 関数 – 手続き型言語:C, Java, Python, … 純 粋 • 測定対象:ステートメント, 条件分岐 論 宣 – 非純粋関数型言語: Lisp, OCaml, … 理 言 • 測定対象:関数 測定不可• 測定困難:測定対象がない、副作用を認めない – 宣言型言語:SQL, HTML – 純粋関数型言語:Haskell, XSLT – 論理型言語:Prolog2012/11/2 ガイオ プライベートセミナー 2012秋 10
    • :ユーザーコード(言語固有処理)全体構成 テストカバレッ :既存外部プログラム(CC,ライブラリ等) :再利用コード(フレームワーク) ジ測定用コード コ 実 カバレッジ カソースコード ー ソースコード 行 バ データ ~~~~ ド ~~~~ 部 0101 レ ~~~~ 埋 ~~~~ ( 0001 ッ ~~~~ め ~~~~ ~~~~ 処 1110 1010 ジ 込 理 表 み 系 示 測定結果 部 ) 部 AST上で埋め込み AST AST AST ソースコード ソースコード コ AST AST AST ~~~~ ー ~~~~ ~~~~ ~~~~ 生 整 操 ド ~~~~ ~~~~ 成 形 作 生 ~~~~ 部 部 部 成 部 2012/11/2 ガイオ プライベートセミナー 2012秋 11
    • ソースコード AST ~~~~AST生成部 ~~~~ ~~~~• 機能:構文解析器(パーサ) – ソースコードからASTを生成 豊富なXML処理 – ASTはXMLオブジェクトで表現 • 既存XML技術を利用:LINQ to XML, SAX, DOM, XSLT• 利用可能な外部プログラム 豊富な実装支援 – コンパイラコンパイラ(CC): SableCC, ANTLR – ライブラリ: Pork, Python Standard Library• 必要なユーザーコード – CCの文法ファイル、ライブラリ呼び出しコード2012/11/2 ガイオ プライベートセミナー 2012秋 12
    • AST ASTAST整形部• 機能: 埋め込みの前処理 – ノードの追加 • 省略形if文をブロックを作って通常形に変換• 実装:必要なユーザーコード – ノードの追加 if (a == 0) puts("a==0") if (a == 0) { puts(”a == 0”) }2012/11/2 ガイオ プライベートセミナー 2012秋 13
    • AST AST AST操作部• 機能:測定用コードの埋め込み 1. 埋め込み位置の特定 2. 測定用コードの変換 stmt (0); 3. 測定用コードの埋め込み• Template Method Pattern によるスケルトンコード提供• 必要なユーザーコード – 測定対象ノードか判定(位置特定)ASTの類似構造を利用 – 測定用コードのAST表現への変換 2012/11/2 ガイオ プライベートセミナー 2012秋 14
    • AST ソースコード ~~~~コード生成部 ~~~~ ~~~~ ~~~~• 機能: ASTからコードを生成 if ( ) – AST生成部でノードにトークンを記憶 a < 0 – 記憶したトークンを基にコードを生成 if (a < 0)• 実装:汎用的なコードを提供 – ノードが保持するトークンの出力• 実装:必要なユーザーコード – 保持していない特殊なトークンの出力 • 例) Pythonにおけるインデント2012/11/2 ガイオ プライベートセミナー 2012秋 15
    • カバレッジ表示部• 機能:結果表示 – 任意の処理系でテスト実行して得られた結果 – 各網羅率の表示 • 命令網羅, 分岐網羅, 条件網羅, 判定条件網羅 – 階層構造のタグを利用して結果をフィルタリング • 名前空間によるフィルタリングの実現• 実装:ユーザーコードは不要 – 完全な実装の提供 •表示部の拡張も可能 •全言語共通のUIを提供2012/11/2 ガイオ プライベートセミナー 2012秋 16
    • 実装例:Python言語における命令網羅public class 再利用コード(フレームワーク) AtomicStatementSelectorForPython : AtomicStatementSelector{ protected override bool IsStatementElement(XElement e) { return e.Name.LocalName == "simple_stmt"; } protected override bool IsStatementSepartor(XElement e) { return e.Name.LocalName == "SEMI"; }} Template Method Pattern Pythonの実装例 ユーザーコード(言語固有処理) 2012/11/2 ガイオ プライベートセミナー 2012秋 *古い内容です 17
    • ガイオ社のツールへの組み込み • OCCFが提供する抽象クラスをガイオ社側の クラスが継承することで、モジュール結合 – OCCFは測定結果をガイオ社側のDBに保存Databaseを介して 測定結果を表示 Viewer Viewer 測定結果を ガイオ社側の Instrumenter InstrumenterDatabaseに保存 Impl for tool テンプレート Database メソッドパターン Java で結合可能な設計 C++ Analyzer Java Analyzer OCCFの ソースコード Java解析エンジン ガイオ・テクノロジー社 OCCF を利用 の単体テストツール 2012/11/2 ガイオ プライベートセミナー 2012秋 18
    • 定量的評価:開発コスト 院生4人で実 験 2500 Java Python 実装内容 達成人数 平均時間 2031 2000 新カバレッジ追加 4人 13.5分 (OCCF) 1500LOC [ 行 ] Python3への対応(OCCF) 4人 47.5分 1056 1000 90% 新カバレッジ追加(SCP) 0人 ― 削減 Python3への対応(SCP) 0人 ― 500 125 131 93 0 SCP = Statement Cobertura EMMA OCCF(Java) SCP OCCF(Python) 4時間では未完了 Coverage for Python • 開発コストの低減 • 容易な機能拡張 – 埋め込み処理部分のLOC – Python2への新しいカバ レッジの追加 – 再利用コードの提供 – Python2からPython3へ • 90%程度の削減を実現 の変更対応 2012/11/2 ガイオ プライベートセミナー 2012秋 19
    • 定性的評価:統一性、柔軟性、完全性• 統一的なテストカバレッジの測定 統一性 – Java, C, Pythonの3言語対応を実装 – C#, Ruby, JavaScript, Luaの部分実装 – 全て4種類のカバレッジに対応 柔軟性 • 命令網羅, 分岐網羅 • 条件網羅, 判定条件網羅• 柔軟なテストカバレッジの測定 – 新しいカバレッジの追加 完全性• 完全なテストカバレッジの測定 – デッドコードも測定対象に含む2012/11/2 ガイオ プライベートセミナー 2012秋 20
    • 複数言語対応カバレッジ測定環境のまとめ 機能拡張の支援• OCCFの提供 Python – 柔軟な測定 対応カバレッジの統一 Java – 統一的な測定 C 共通処理の 再利用 – 開発コストの低減 コード上埋め込み フレームワーク – 完全な測定 – オープンソースとして公開 Google Code• ガイオ社の単体テストツールと結合成功• 低コスト、統一性、柔軟性、完全性の実現2012/11/2 ガイオ プライベートセミナー 2012秋 21
    • テストカバレッジ研究の最新動向その12012/11/2 ガイオ プライベートセミナー 2012秋 22
    • Fault(Bug) Localization• 従来のテスト手法は欠陥のある/なし判定に焦点 – ソースコードがバグを含んでいるかいないかを判定• テスト結果からソースコード中の欠陥の位置を推定 – どのステートメントがバグを含んでいそうか?• バグを含む可能性 Risk (suspiciousness) の算出 – テスト結果とカバレッジ情報から算出 – テスト失敗時に実行したステートメントは怪しい – テスト成功時に実行したステートメントは怪しくない• 様々なRiskの算出式:Tarantula, Ochiai など 2012/11/2 ガイオ プライベートセミナー 2012秋 23
    • Riskの算出例 TC1 TC2 TC3 TC4 TC5 T(Sn) F(Sn) %T(Sn) %F(Tn) Risk S1 × ✓ × ✓ ✓ 3 2 1.000 1.000 0.500 S2 × ✓ ✓ 2 1 0.667 0.500 0.429 S3 × × 0 2 0.000 1.000 1.000 S4 × ✓ 1 1 0.333 0.500 0.600 S5 ✓ ✓ 2 0 0.667 0.000 0.000 Test Pa Pa Pa Fail Fail 3 2 成否 ss ss ssS: ステートメント, TC: テストケース Rank RiskTarantula Risk = %F(STn) / { %F(STn) + %T(STn) } 1 ST3 1.000 2 ST4 0.600T(All), F(All) : 全ての成功(失敗)テストケース数 3 ST1 0.500T(Sn), F(Sn) : Snを通る成功(失敗)テストケース数 4 ST2 0.429%T(Sn), %F(Sn) : T(Sn) / T(All) , F(Sn) / F(All) 5 ST5 0.000 2012/11/2 ガイオ プライベートセミナー 2012秋 24
    • Riskの可視化例 (Tarantula) テストケース 3,3,5 1,2,3 3,2,1 5,5,5 5,3,3 2,1,3 Mid() { int x,y,z,m; (x, y, z)01: read(“Enter 3 numbers:”, x,y,z); ✓ ✓ ✓ ✓ ✓ ×02: m = z; ✓ ✓ ✓ ✓ ✓ ×03: if (y<z) ✓ ✓ ✓ ✓ ✓ ×04: if (x<y) ✓ 実行したか05: m = y; ✓ 否か06: else if (x<z) ✓ ✓ ×07: m = y; ✓ ×08: else ✓ ✓ ✓09: if (x>y) ✓10: m = y; ✓11: else if (x>z) 未実行箇所12: m = z;13: print(“Middle number is:”, m); ✓ ✓ ✓ ✓ ✓ × } P P P P P F テスト結果 2012/11/2 ガイオ プライベートセミナー 2012秋 25
    • Fault Localizationの有効性• デバッグ作業の効率化 – テスト失敗時のデバッグ箇所の優先順位付け – 効率の良いバグ修正が可能• テスト設計の改善 – Riskに差異がでない=テストが不十分• 導入容易性 – テスト結果とカバレッジ情報から算出可能 コストを抑えつつ 高品質なソフトウェア開発を実現2012/11/2 ガイオ プライベートセミナー 2012秋 26
    • 論文件数の推移IEEE Xplore “Fault Localization” or “Bug Localization” の検索結果数8070605040302010 0 年代 2012/11/2 ガイオ プライベートセミナー 2012秋 27
    • 代表的なツール • Tarantula(現在は非公開?)* • OCCFも複数言語に対応したRisk算出が可能*) Jones, J.A.; Harrold, M.J.; Stasko, J.; , "Visualization of test information to assist fault localization," Proceedings of the 24rdInternational Conference on Software Engineering (ICSE 2002), pp.467-477, 25-25 May 2002. 2012/11/2 ガイオ プライベートセミナー 2012秋 28
    • Fault localization のまとめ• 従来のテスト手法は欠陥のある/なしを判定• テスト結果とカバレッジ情報から ソースコード中のバグの位置を推定 – デバッグ作業の効率化 – テスト設計の改善• 少数ではあるがツールが存在 – 様々なRisk算出式が存在 – OCCFもTarantulaのRisk算出式に対応2012/11/2 ガイオ プライベートセミナー 2012秋 29
    • テストカバレッジ研究の最新動向その22012/11/2 ガイオ プライベートセミナー 2012秋 30
    • カバレッジ100%は本当に安心か• テストカバレッジはテストの品質を 担保するための重要なテストの評価指標• テストカバレッジが100%なら本当にテス トの品質は高い=バグを検出可能なのか?• 右のコードはカバ int add(int a, int b) { レッジ100%だが } return a * b; // バグ(+ではなく*) 製品コード バグを検出不可 @Test void add1_2_should_return_3() {• テストコードに int result = add(1, 2); Assertionがない! } テストコード – 質の低いテスト2012/11/2 ガイオ プライベートセミナー 2012秋 31
    • テストオラクル• テストの成否を判定するための仕組み – 実行結果と比較するための期待結果そのもの – 期待結果を自動生成するためのプロセス• テストコード中のAssertionもテストオラクル• テストカバレッジは int add(int a, int b) { return a + b; テストシナリオの } 製品コード 評価指標 @Test void add1_2_should_return_3() {• テストオラクルの // テストシナリオ 評価指標は? int result = add(1, 2); – これまでの研究は // テストオラクル テストオラクル品質を assertEquals(3, result); 無視してテスト品質を } テストコード 語っていたのでは?**) Staats, M.; Whalen, M.W.; Heimdahl, M.P.E.; , "Programs, tests, and oracles: the foundations of testing revisited," 201133rd International Conference on Software Engineering (ICSE), pp.391-400, 21-28 May 20112012/11/2 ガイオ プライベートセミナー 2012秋 32
    • Checked Coverage • Schulerらによって提案されたカバレッジ* • テストオラクルで検査する出力に依存する 実行済みステートメント数から網羅率を算出 – 従来カバレッジ:実行済みステートメント • 右のテストでは int add(int a, int b) { callCount++; //メソッド呼び出し回数 callCountの値を return a + b; 検査していない } 製品コード • 従来カバレッジは100% @Test void add1_2_should_return_3() { 提案カバレッジは50% int result = add(1, 2); assertEquals(3, result); • 本当に検査した部分から } テストコード カバレッジを算出する*) Schuler, D.; Zeller, A.: "Assessing Oracle Quality with Checked Coverage," 2011 IEEE Fourth International Conferenceon Software Testing, Verification and Validation (ICST), pp.90-99, 21-25 March 2011.2012/11/2 ガイオ プライベートセミナー 2012秋 33
    • Webアプリの動的部分 に着目したカバレッジ • 我々が提案するWebアプリ向けカバレッジ* • Webアプリの動的に生成・変形される部分に ついて、検査済みの部分の割合を算出 欠陥が – Webアプリのテストオラクルの評価指標 潜みやすい “Test scenario”のGoogle検索結果 “Test oracle”のGoogle検索結果*)坂本一憲, 海津智宏, 波村大悟, 鷲崎弘宜, 深澤良彰: "Webアプリの動的部分に着目したグレーボックス統合テストとテンプレート変数カバレッジの提案", 第19回 ソフトウェア工学の基礎ワークショップ論文集, 8 pages, 2012. ©Google Inc. 2012/11/2 ガイオ プライベートセミナー 2012秋 34
    • テストオラクルの評価指標のまとめ• 従来のカバレッジはテストシナリオの 評価指標として有用• テストオラクルに対する評価指標が必要• テストの品質とは テストシナリオの品質×テストオラクルの品質 である – どちらか一方が欠けるとテストが機能しない*• テストオラクルの品質改善手法が求められる*) Shrestha, K.; Rutherford, M.J.; , "An Empirical Evaluation of Assertions as Oracles," Software Testing, 2011 IEEE FourthInternational Conference on Verification and Validation (ICST), pp.110-119, 21-25 March 2011. 2012/11/2 ガイオ プライベートセミナー 2012秋 35
    • テストカバレッジ研究の最新動向その32012/11/2 ガイオ プライベートセミナー 2012秋 36
    • テストケースの増大・重複• 原因1:テストケース自動生成手法の適用• 原因2:テストコードが保守対象になりにくい• 問題1:テストケース増大による効率性の低下 – テストの実施時間の増大 – 人手によるテスト実施範囲の限定が必要 – しかし、実施範囲を狭めると検査漏れが生じる・・• 問題2:テストケース重複による保守性の低下 – DRY(Don’t repeat yourself)原則への違反 – 可読性や変更容易性の低下 – テストコードも製品コードも同じソースコード• 不要なテストケースを削除しよう!2012/11/2 ガイオ プライベートセミナー 2012秋 37
    • 解決:テストカバレッジに基づいた Test case minimization• テストケースの包含関係の算出 – テストの検査内容(実行ステートメントなど)が 等しければ重複したテストケースと考える – テストカバレッジの観点を利用 • 命令網羅,分岐網羅,全パス網羅 • ステートメント単位、条件分岐単位、パス単位 – OCCF上で実装済み• 検出された重複テストコードを削除候補 – テストの量と品質のトレードオフで削除 – テストの効率性と保守性の向上2012/11/2 ガイオ プライベートセミナー 2012秋 38
    • カバレッジに基づく重複検出例01: String fizzBuzz(int x) { void test0は0:が返される() {02: String str = x + ":"; assert(fizzBuzz(0) == "0:");03: if (x % 3 == 0) { }04: str += "Fizz"; void test3は3:Fizzが返される() {05: }06: if (x % 5 == 0) { assert(fizzBuzz(3) == "3:Fizz");07: str += "Buzz"; }08: } void test5は5:Buzzが返される() {09: retrun str; assert(fizzBuzz(5) == "5:Buzz");10: } } void test15は15:FizzBuzzが返される()• 実行パス(行番号の遷移) { –test0:2→3→6→9 assert(fizzBuzz(15)=="15:FizzBuzz"); –test3:2→3→4→6→9 } –test5:2→3→6→7→9 –test15:2→3→4→6→7→9 • 全パス網羅(実行順序を考慮)• 命令網羅(実行順序を考慮しない) – test0,3,5,15は互いに独立• test15がtest0,3,5を全て包含 2012/11/2 ガイオ プライベートセミナー 2012秋 39
    • Test case minimization のまとめ• テストコードもソースコード同様に保守が必要 – 不必要・重複したテストケースは削除すべき – テストを実行するリソースにも限りがある• 重複テストケースをカバレッジに基づいて検出 – あるテストが実行するステートメント郡の全てを 他のテストが実行する場合はテストが重複 – OCCFもカバレッジに基づいた検出機能を持つ – ただし、テストオラクルは考慮していない• 今後はテストオラクルも含めた重複判定が必要 2012/11/2 ガイオ プライベートセミナー 2012秋 40
    • 全体のまとめ1. 複数言語対応カバレッジ測定環境 – OpenCodeCoverageFrameworkのガイオ・テク ノロジー社単体テストツールへの組み込み事例2. Fault localization – テスト結果とカバレッジから欠陥位置の推定3. テストオラクルの評価指標 – テストの品質評価にはオラクルの品質評価が必要4. Test case minimization – 不要なテストケースを削除した効率の良いテスト2012/11/2 ガイオ プライベートセミナー 2012秋 41