180 likes | 246 Views
テスト駆動開発を支援するための デバッグ関心事グラフ. 塩塚 大 鵜林 尚靖 九州工業大学. 概要. 今回はDCG生成の 仕組み について説明. TDD. 生成. 実行. DCG. 利用. モチベーション 同じバグ,失敗を繰り返したくない しかし,修正過程をいちいち手作業で記録するのは大変 アプローチ 修正過程 を 自動収集 する仕組みを提案 テスト駆動開発(TDD)に着目しテスト失敗 / 成功をもとに実現 修正過程の表現 ⇒ デバッグ関心事グラフ( Debug Concern Graph: DCG). 目次. 1.問題意識
E N D
テスト駆動開発を支援するためのデバッグ関心事グラフテスト駆動開発を支援するためのデバッグ関心事グラフ 塩塚 大 鵜林 尚靖 九州工業大学
概要 • 今回はDCG生成の仕組みについて説明 TDD 生成 実行 DCG 利用 • モチベーション • 同じバグ,失敗を繰り返したくない • しかし,修正過程をいちいち手作業で記録するのは大変 • アプローチ • 修正過程を自動収集する仕組みを提案 • テスト駆動開発(TDD)に着目しテスト失敗/成功をもとに実現 • 修正過程の表現 ⇒ デバッグ関心事グラフ(Debug Concern Graph: DCG)
目次 1.問題意識 2.デバッグ関心事グラフ(DCG) 3.DCGを用いたデバッグ 4.議論と今後の課題
1.問題意識 失敗したケース AST操作で生じたバグ -insertメソッドー 修正過程を記録する際の課題
失敗したケース • 慣れていない言語でプログラミングし失敗したケース • PHP言語の例 • 型が曖昧な言語 ⇒同じ変数が配列になったりオブジェクトになったりする • このことを十分に理解していなくて発生したバグ ⇒具体例:AST(抽象構文木)操作で発生したバグ
AST操作で発生したバグ -insertメソッドーAST操作で発生したバグ -insertメソッドー ASTへの入力(括弧あり) ASTへの入力(括弧なし) if ( 1 ) { return $a == 1; } if ( 1 ) return $a == 1; エラー発生 ASTへ変換 ASTへ変換 IfStatement Object |_ $condition => 1 |_ $statements Array |_ [0] => Statement Object |_ $expr => return $a == 1; IfStatement Object |_ $condition => 1 |_ $statements Statement Object |_ $expr => return $a == 1; オブジェクト 配列 ASTのイメージ ASTのイメージ • insertメソッドを実装中 • insertの定義:ASTを操作し指定した箇所に式を挿入するメソッド • insert内では,あるクラスのフィールド$statementsを参照(reads) • $statementsを常に配列であると勘違いし実装 • しかし,実はオブジェクトの場合もありテストtestInsertでエラー発生
修正過程を記録する際の課題 testInsert succeeds error insert(Ver. 0.1) insert(Ver. 0.2) アプローチのイメージ • 既存のアプローチ • 修正過程のドキュメント化/コミットの際のコメント⇒手作業で作成するのは大変 • バージョン管理ツール⇒履歴だけ見ても,どういったバグ/テストに関わったか分からない • 本研究のアプローチ • 修正過程の自動収集 ⇒手作業の負担を軽減 • バージョン間にテスト結果を関連させて表現⇒ある修正に関係したバグ,テスト,テスト結果が分かる
2.デバッグ関心事グラフ(DCG) 自動収集の仕組み 修正履歴の管理方法 関心事グラフとの関係 -Debug Concern Graph-
自動収集の仕組み 例:insertメソッドの修正過程の自動収集 TDDプロセス b) コード修正 c) testInsertの成功 a) testInsertの失敗 ① ルートノード新規作成 ② testInsertの追加 ③ insert(Ver. 0.1)の追加 ④ $statementsの追加 ⑤insert(Ver. 0.2)の追加 ⑥修正履歴の追加 ⑦修正理由の追加 DCGプロセス ① :テストの失敗を 契機に作られる insertのバグ修正(ルート) ⑦ adds to adds to :テストの成功を 契機に作られる 修正理由 adds to ⑥ ② testInsert 修正履歴 :開発者が適宜付け足す error succeeds ⑤ ③ 「この修正はこのテストでエラーが発生したからなんだ」というのが自動で残る! insert(Ver. 0.1) insert(Ver. 0.2) reads reads $statements ④
修正履歴の管理方法 Ver. 0.2 差分n insertのバグ修正(ルート) 差分1 Ver. 0.1 adds to adds to 修正理由 adds to testInsert 修正履歴 error succeeds テスト失敗 insert(Ver. 0.1) insert(Ver. 0.2) reads reads テスト単位でリプレイが可能! 普段は圧縮,必要に応じて展開 $statements • テスト失敗の後に再びテスト失敗した場合 ⇒テスト失敗ごとにコードの差分だけを保存
関心事グラフとの関係 Robillard, M. P., et al. 2002 クラス • class ASTConverter { • public function insert ($IfSta, $sta, $idx) { • $block = &$IfSta->statements; • if (!is_array($block)) • $block = array($block); • $pre = array_slice($block, 0, $idx); • $post = array_slice($block, $idx); • $block = array_merge($pre, array($sta), $post); • } • public function replace ($IfSta, $sta, $idx) { • …. • } • } ASTConverter declares メソッド declares 抽象化 insert reads replace フィールド $statements PHPプログラム 関心事グラフ DCG = 関心事グラフ + TDD • 関心事グラフ • プログラムの構造を大ざっぱに理解したい例:クラス間をまたいで,大規模なプログラムの修正をするときなど • クラス/メソッド/フィールドをdeclares, reads, writes などを関係とするグラフで表現
insertのバグ修正(ルート) adds to adds to adds to ASTConverter testInsert 修正履歴 修正理由 declares error succeeds declares insert(v 0.2) insert(v. 0.1) reads reads replace $statements DCG DCG:あるデバッグに関連した主要な要素を大ざっぱに把握したい例:あるバージョンでテスト失敗の原因となった要素を知りたいときなど⇒ DCG = 関心事グラフ + 修正情報(テスト情報/バージョン情報)
3.DCGを用いたデバッグ AST操作で生じたバグ -replaceメソッドー DCGの選択 DCGの利用
AST操作で発生したバグ -replaceメソッドーAST操作で発生したバグ -replaceメソッドー ASTへの入力(括弧あり) ASTへの入力(括弧なし) if ( 1 ) { return $a == 1; } if ( 1 ) return $a == 1; エラー発生 ASTへ変換 ASTへ変換 IfStatement Object |_ $condition => 1 |_ $statements Array |_ [0] => Statement Object |_ $expr => return $a == 1; IfStatement Object |_ $condition => 1 |_ $statements Statement Object |_ $expr => return $a == 1; オブジェクト 配列 ASTのイメージ ASTのイメージ • replaceメソッドを実装中 • replaceの定義:ASTを操作し式を別の式で置換するメソッド • replace内では,あるクラスのフィールド$statementsを参照 • $statementsを常に配列であると勘違いし実装 • しかし,実はオブジェクトの場合もありテストtestReplaceでエラー発生
DCGの選択 ASTConverter ASTConverter • class ASTConverter { • public function insert ($IfSta, $sta, $idx) { • …. • } • public function replace ($IfSta, $sta, $idx) { • $block = &$IfSta->statements; • $block[$idx] = $sta; • } • } declares declares replace insert reads reads $statements $statements replaceのDCG(一部) insertのDCG(一部) • 既存のDCGを利用したい • 類似したDCGを探す⇒部分グラフの探索
DCGの利用 例:「insertのバグ修正」のDCGを利用したreplaceのデバッグ TDDプロセス b) コード修正 c) testReplaceの成功 a) testReplaceの失敗 ⑦ replace(Ver. 0.2)の追加 ⑧ 修正履歴の追加 ⑨ 修正理由の共有 ④ 「insertのバグ修正」 DCGの参照 ⑤ 修正理由の確認 ⑥ 修正履歴の取出しと 修正方法の決定 ① ルートノード新規作成 ② testReplaceの追加 ③replace(Ver. 0.1)の追加 DCGプロセス ④ ① replaceのバグ修正 insertのバグ修正 adds to ⑨ ⑤ adds to adds to adds to adds to adds to ⑧ 修正理由 ② ⑥ 修正履歴 testInsert testReplace 修正履歴 succeeds error succeeds error ⑦ ③ insert(Ver. 0.1) insert(Ver. 0.2) replace(Ver. 0.1) replace(Ver. 0.2) reads reads $statements
議論と今後の課題 • 議論 • 選択方針 • 膨大なDCGから欲しいものをどうやって見つけるか • グラフ間の距離 • マイニング • 利用方針 • 見つけた後それをどう活用するか • 単純に参照するだけなのか • 履歴/テストを活用し,ある程度自動修正できないのか • グラフ構造 • ルートノードはそもそも必要なのか • 今後の課題 • 今回はDCG生成の仕組みを説明今後は上記の解決と,システムの実装