「automated oracle creation support, or: how i learned to stop worrying about fault propagation and...
TRANSCRIPT
2012年 6月 28日
対象: コンピュータ科学専攻の修士・博士学生
(ソフトウェア工学専攻とは限らない)
発表時間: 25分 1
Automated Oracle Creation Support, or: How I Learned to Stop Worrying about Fault Propagation and Love Mutation Testing (ICSE2012)
輪講用資料
発表論文
“Automated Oracle Creation Support, or: How I Learned to Stop Worrying about Fault Propagation and Love Mutation Testing”
- テストオラクル(後述)の選択を自動化する
By. Matt Staats (Korea Advanced Institute of Science & Technology)
Gregory Gay, Mats P. E. Heimdahl (University of Minnesota)
34th International Conference on Software Engineering
(ICSE 2012, Acceptance ratio: 21%)
2
テストとは
テスト:実装の正しさを,実行して確かめること
3
// x2 + |x| + 5を求める int calc(int x) { int val = x * x; if (x > 0) { val += x; } else { val -= x; } return val + 5; }
X=3とする
正しいかわからないプログラム
テストオラクルとは
オラクル:正しい振舞いを決めるもの
4
ここでのvalは9である // x2 + |x| + 5を求める int calc(int x) { int val = x * x; if (x > 0) { val += x; } else { val -= x; } return val + 5; }
この分岐は実行されない
出力は5以上である
出力変数だけでなく,内部変数もオラクルに利用することで,
テストの結果が改善できる (Staats, 2011)
X=3とする
オラクル
期待値オラクル
↑本研究の対象
論文概要
問題:
オラクルの選択は重要だが,現状は出力変数のみ着目
全ての内部変数に期待値を設定するのはコスト大
目的: テストオラクルの選択を自動化したい
解法: ミューテーションテストを応用して,各変数をランク付け,
ランク上位の変数をテストオラクルとして利用
結果: 4つの実アプリケーションに適用
標準的なやり方と比べ最高145.8%の性能向上 5
提案手法の使われ方
6
プログラム
テスト入力
ミュータント
変数の有効性 ランキング
オラクルの変数集合
テスト実行者 期待値オラクルの集合
(1)ミュータント生成
(2)テストを実行 変数の有効性を調べる
(3)ランキングの上位から,必要そうな変数を選択
入力に応じて, 変数に期待する値を設定
提案手法
既存研究が
多く存在 - 少ない変数 - 欠陥発見に役立つ
{x, y,…}
{x=3, y=5,…}
前提知識:ミューテーションテスト(1/2)
7
assertEqual( 1, doubledDiff(1, 0));
assertEqual( 12, doubledDiff(4, 2));
テストの例) 2乗差を求めるメソッドdoubledDiff(a, b)のテスト
int doubledDiff(int a, int b) { int c = a + b; int d = a – b; return c * d; }
テスト1
テスト2
assertEqual( 5, doubledDiff(3, 2));
テスト3 成功
成功
成功
どのテストが「良い」だろうか?
テストの欠陥発見能力を知りたい
前提知識:ミューテーションテスト(2/2)
8
assertEqual( 1, doubledDiff(1, 0));
assertEqual( 12, doubledDiff(4, 2));
ミュータント:プログラムの一部を変換して欠陥を埋め込んだもの
テスト1
テスト2
assertEqual( 5, doubledDiff(3, 2));
テスト3
int doubledDiff(int a, int b) { int c = a - b; int d = a – b; return c * d; }
int doubledDiff(int a, int b) { int c = a + b; int d = a – b; return c / d; }
ミュータント1
ミュータント2
成功
成功
成功
失敗
失敗
失敗
テスト2が良い(欠陥発見能力が高い)とわかる
欠陥
欠陥
提案手法の使われ方
9
プログラム
テスト入力
ミュータント
変数の有効性 ランキング
オラクルの変数集合
テスト実行者
(1)ミュータント生成
(2)テストを実行 変数の有効性を調べる
(3)ランキングの上位から,必要そうな変数を選択
提案手法
提案手法概観
10
プログラム
テスト入力
ミュータント
変数の有効性 ランキング
オラクルの変数集合
テスト実行者
(1)ミュータント生成
(2)テストを実行 変数の有効性を調べる
(3)ランキングの上位から,変数を選択
提案手法
1. ミュータントの生成
一般的なミューテーションテスト[1]の手法通り
演算子(+, -, *, /, !, ==, など)の置換
Boolean値の反転
定数の置換
など
11 [1] An analysis and survey of the development of mutation testing, Yue Jia, Mark Harman(2010, IEEE Software Engineering)
int doubledDiff(int a, int b) { int c = a - b; int d = a – b; return c * d; }
演算子の置換
ミュータント
int doubledDiff(int a, int b) { int c = a + b; int d = a – b; return c * d; }
プログラム
2. 変数へのランク付け(1/3)
各ミュータントに対してテストを実行し,
変数の値を毎ステップ監視
12
プログラム
ミュータント1
ミュータント2
ミュータント3
テスト入力
x y ret
プログラム 5 10 30
ミュータント1 -9 10 -27
ミュータント2 6 10 30
ミュータント3 5 -8 30
ミュータント4 -4 10 -20
例)ある時点での変数の値
3kill 2kill 1kill ミュータント4
元のプログラムと違った値を示す変数はバグ検出に役立ちそう
2. 変数へのランク付け(2/3)
killできるミュータント数順に変数を並べれば良いとも限らない
← 変数間に依存関係がある場合うまくいかない
13
x y ret
プログラム 5 10 30
ミュータント1 -9 10 -27
ミュータント2 6 10 30
ミュータント3 5 -8 30
ミュータント4 -4 10 -20
3kill 2kill 1kill
例) retでkill出来るミュータントは必ずxでkillできる
なるべく少ない個数の変数で,
すべてのミュータントをkillしたい
集合被覆問題として解ける
貪欲法による近似解法[2]が有名
2. 変数へのランク付け(3/3)
貪欲法による変数へのランク付け
アルゴリズム:
14
RankedVariableに追加された順に,ランクが高いとする.
1. RankedVariableを空集合で初期化
2. UnkilledMutantsにすべてのミュータントを代入
3. UnkilledMutants中のmutantを最も多くkillできる 変数vを選択し,RankedVariableに加える
4. UnkilledMutantsが空になるまで,3を繰り返す
3. 適切なオラクル数の見積り(1/2)
何個の変数をオラクルに使うべきか?
多くの変数を使う
○ 欠陥発見に役立つ
× 人間が期待値を設定するのが大変
最適な個数はわからない → 選択の基準を提供
15
3. 適切なオラクル数の見積り(2/2)
Fault finding effectiveness
:= |その変数集合で𝑘𝑖𝑙𝑙できるミュータントの数|
|すべてのミュータントの数|
オラクルに使う変数の数を1つ増やすと,effectivenessは上昇する
その上昇度合が閾値以下になると,十分なオラクル数だと言える
16 0
20406080
100
0 5 10 15
eff
ective
ness
オラクルサイズ
オラクルサイズとeffectivenessの関係(イメージ)
研究課題(RESEARCH QUESTION)
RQ1: 提案手法は,オラクルデータの選択に関して,標準のやり方と比べて実用上優れているだろうか?
RQ2: ミューテーションベースの手法は潜在的にどれだけの最大効率を持つだろうか.また,実用上の効率と最大効率はどの程度異なるだろうか?
RQ3: テストに対する入力の違いはどの程度,提案手法の効率に影響するだろうか?
17
実験設定(1/2)
テスト対象:
航空機器の実アプリケーション
Simulink(組み込みシステム向けの,モデル駆動開発ツール)
で作られたモデルから自動生成されたLustreコード DWM1, 2: 商用コクピットシステムのウィンドウマネージャの一部
Vertmax, Latctl: フライトガイダンスシステムの一部
テストの入力(RQ3):
カバレッジ基準を満たすテストケースを自動生成する既存手法[4]
を利用,以下の2つのカバレッジに対してそれぞれ10通りのテストスイートを生成
ブランチカバレッジ
MC/DC(Modified Condition/DeCision)カバレッジ[3] 18
実験設定(2/2)
ミュータント:
250のミュータントを生成し,半分を訓練用,残りを評価用
オラクル生成方法(RQ1, RQ2):
Random: 出力変数および内部変数からランダムにn個選択
Output-base: 出力変数をまずオラクルに加え,
その後,内部変数からランダムに選択
Mutation-based: 提案手法
Idealized Mutation-based:
評価用のデータに提案手法を適用
生じるバグをあらかじめ知っている場合に相当する
19
結果:4手法の性能比較
20 縦軸: Fault finding effectiveness =
|その変数集合で𝑘𝑖𝑙𝑙できるミュータントの数|
|すべてのミュータントの数|
横軸: オラクル集合の変数の数
考察: 提案手法のOUTPUT-BASEに対する性能改善率
21
RQ1: 提案手法は,オラクルデータの選択に関して,標準のやり方と比べて実用上すぐれているだろうか?
- 最大145.8%の性能向上,概して10-30%程度性能向上 - オラクルサイズ < 出力変数総数のとき,提案手法が優れており, オラクルサイズ == 出力変数総数のとき同じような性能を示し, その後提案手法が優位性を示す傾向
10%以上の性能向上
考察: 提案手法のOUTPUT-BASEに対する性能改善率
22
RQ1: 提案手法は,オラクルデータの選択に関して,標準のやり方と比べて実用上すぐれているだろうか?
→ 変数に優先付けをすることは役立つだろう
- 最大145.8%の性能向上,概して10-30%程度性能向上
- オラクルサイズ < 出力変数総数のとき,提案手法が優れており,
オラクルサイズ == 出力変数総数のとき同じような性能を示し,
その後提案手法が優位性を示す傾向
結果と考察: 理想的な場合の提案手法への性能改善率
23
RQ2:ミューテーションベースの手法は潜在的にどれだけの最大効率を持つだろうか.また,実用上の効率と最大効率はどの程度異なるだろうか?
理想的な場合のほうが高い欠陥発見能力
しかし,性能差はさほどではない
すべて正の値
多くの値が20%以下
考察:入力による違い
RQ3: テストに対する入力の違いはどの程度,提案手法の効率に影響するだろうか? → 左右のグラフはどう違うか,ということ
24
MC/DCカバレッジの方が,欠陥発見能力が概ね高かった
一方で,グラフの形は概ね似ている
→入力による影響を受けない一般的な傾向と推測できる
100 80
まとめ
ミューテーションテストの考えを利用
テストオラクル,特に変数の期待値オラクルを対象に
有用な変数集合を自動で選択する手法を提案
実アプリケーション(欠陥は人工)に対して評価
提案手法は,ナイーブな選択の仕方に比べて
最大で145.8%,概して10-30%程度の性能向上
25
私見(1/2)
○「内部変数も使えば欠陥発見能力を高く出来る」という,当たり前っぽいけどあまり研究されてなかった(らしい)ところをちゃんと実験してそれらしい結果をまとめているのはすごい
×比較対象(Output-base)が単純すぎる.内部変数の選択はランダムなので,提案手法が勝ちそうなのはあまりに明らか
開発者のヒューリスティクスによる選択との比較があると良かった
× RQ2の考察が乱暴
他のドメインに試すとどうなるのか気になる
26
私見(2/2)
△著者らの述べる,提案手法の使われ方がいまいちわからなかった.すでに実装があるなら,変数の期待値は機械的に設定できるのでは.
×人間がオラクルを設定するならば,内部変数の値を設定するのは,出力変数の値と比べて困難なのではないか.
△実験の詳細が不明瞭,対象のコード例や,行数,変数の数などを示して欲しい
△テストの集合に対してオラクルになる変数集合がある,
という問題設定がよくわからない.テストメソッドに対してオラクルが存在するのが普通な気がする. 27
集合被覆問題(SET COVER PROBLEM)
29
ある集合Uと,その部分集合の族 F = {Si} (i = 1, …, n)
U = S1∪…∪Snのもと,Fの部分集合Cで,
∀e∈U, e∈C
かつ|C|が最小となるようなものを求める問題
最適解を求める問題はNP困難
※族とは,集合を要素にもつ集合 ex. {{}, {1, 2}}
貪欲法による解法がよく知られている.
まだ覆われていない要素を一番多く含むSiを選ぶという
作業を繰り返せば良い.
貪欲法の近似率はln|U| + 1
2. 変数へのランク付け(2/3)補足
各変数vに対して,vがkillできるミュータントの集合をMvとする
M = M1∪…∪Mnとする
M1,…Mnからなるべく少ない個数の集合を選び,
その和集合Msubが
∀m∈Mについて,m∈Msubとなってほしい
→集合被覆問題
30
Mx = {m1, m2, m4}
My = {m3}
Mret = {m1, m4}
M = {m1, m2, m3, m4}
Mx とMyを選ぶと良い
x y ret
プログラム 5 10 30
ミュータント1 -9 10 -27
ミュータント2 6 10 30
ミュータント3 5 -8 30
ミュータント4 -4 10 -20
MC/DC カバレッジ
31
用語定義:
if ( (a == b) && (c == d) || (e == f) ) then
MC/DCカバレッジを満たすとは,以下の1~3が成立すること
1. プログラムのすべてのentry/exit点が少なくとも一度は実行されている
2. すべてのconditionが取りうる値を少なくとも一度はとっている
3. それぞれのconditionが,自身を含むdecisionに独立に影響することを示されている
3を確かめることにより,decisionも網羅できるので,
ブランチカバレッジ(すべての分岐先を実行)より強い制約
condition decision
参考文献
ミューテーションテスト
[1] An analysis and survey of the development of mutation testing,
Yue Jia, Mark Harman(2010, IEEE Software Engineering)
がとても詳しい.2010出版で,既に120披引用
マシンパワーの増加もあって,最近流行っている?
集合被覆問題の貪欲法による解法
[2] A Greedy Heuristic for the Set-Covering Problem
V. CHVATAL(1979, Mathematics of Operations Research)
有名な解法なので,ぐぐると日本語資料もたくさんある
34
参考文献
MC/DCカバレッジ
[3] DO-178B, Software Considerations in Airborne Systems and Equipment Certification
RTCA(Requirements and Technical Concepts for Aviation ), 1992
厳格なテストを必要とした航空業界の人々が提案
構造カバレッジメトリクスを満たすための,
モデル検査器を用いたテストケース自動生成
[4] Coverage Based Test-Case Generation using Model Checkers
Sanjai Rayaduragam, Mats P.E. Heimdahl, 2001,
IEEE Int’l Conf. on Engineering of Computer Based Systems
35
著者(MATT STAATS)による関連研究
[5] “Programs, tests, and oracles: the foundations of testing revisited” Matt Staats, Michael W. Whalen,
Mats P. E. Heimdahl (ICSE 2011, Distinguished Paper)
- テストオラクルも含めてテスティングの枠組みを再考しよう!
[6] “Better testing through oracle selection” Matt Staats, Michael W. Whalen, Mats P. E. Heimdahl
(ICSE 2011(New Ideas and Emerging Results Track))
- テストオラクルの選択でテストの欠陥発見能力が変わることを調べたよ!
発表論文は,上記2つの論文を元にしたもの 36