slide - POSL

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