«前の日記(2004-01-10) 最新 次の日記(2004-01-13)» 編集

netail.net

自作フリーソフトや,ゲームに関する雑記を公開してます.
日記はソフトウェア工学の論文ネタが中心です.

最近のお知らせ (古いものはこちら)


2004-01-12 古い日記からの変換データ [長年日記]

_ 論文

Suhaimi Ibrahim, Norbik Bashah Idris, Aziz Deraman:Case study: Reconnaissance techniques to support feature location using RECON2.Proceedings of APSEC 2003.

プログラムのあるフィーチャーを含むような,プログラム実行テストケースを "Y" テストケース,含まないようなテストケースを "N" テストケースとして,それらの実行経過の差分を取り出すことでフィーチャーがどこに実装されているかを調べようというものらしい.

ユーザは,テストケースを作り,それを Y/N に分類しておく必要がある.

ケーススタディの結果,そんなにテストケースの個数はいらないが注意深く選んである必要はあるらしい.この手法は,どんな機能があるか,ある程度知っている状態でならプログラムのどこに,その機能が実装しているかを示すのはやりやすい.

弱点は,テストケースが実行できなければならないので,テストケースとして表現しにくい機能ほど見つけにくい.

ちなみに,「部分的な理解だけでもそれなりに保守はできる」ということは既に以下の論文でいわれているらしい.Lakotia, A., "Understanding someone else's code: Analysis of experience", Journal of System and Software,1993, Vol.23, pp.269-275.

_ 論文

Hiralal Agrawal, Richard A. DeMillo and Eugene H. Spafford:Debugging with Dynamic Slicing and Backtracking.Software Practice and Experience, Vol. 23(6), pp.589-616, June 1993. 動的スライスを使えるような環境を GDB ベースで作って,それに加えてバックトラック(「一ステップ前に戻る」)を実装したような環境を作ってみた,という論文. ある地点でブレークして,値がおかしいから動的スライスで前のほうへ戻って原因を調べていく,というもの.いちおうデータのみ,制御のみ,それぞれに注目したスライスも取れるようにしたりとか工夫されていて,成功したテストケースと失敗したテストケースでのスライスの違いなどが役立つだろう,と言っている. プログラムスライスや実行バックトラッキングの限界として,次のようなものを挙げている.
  • 複数回同じ行が実行されたことを,スライスは明示してくれない. (せっかく動的スライスでも,見た目はソースコードだから)
  • スライスは「何が影響しているか」は教えてくれるが,そこから「どの制御あるいはデータが間違ったか」という原因に立ち戻るにはやはりかなりの苦労が必要である.
  • 実行のバックトラックは,システムに対する副作用があるとそこで戻れなくなってしまうので「部分的」バックトラッキングで我慢するか,再実行する仕組みのほうが良いかもしれない.
プログラムスライスも見せ方と使い方が重要,というところではこの論文を引用することになりそう.

_ 論文

Andreas Zeller: Yesterday, my program worked.Today, it does not. Why?, Proceedings of 7th ESEC/FSE 1999

ベースライン(既存プログラム)に対する変更の集合 C を考える.test(x) は テスト結果 PASS, Failure, Unresolved を返す.

ある日,プログラムが動かなくなる: (test(φ) = PASS) ∧ test(C) = FAIL )

変更集合 C を適当に組み替えて(バージョン管理ツールなどを使って),どの変更でプログラムが動かなくなったかを調べる.

このとき,変更は [単調] である.∀c ⊆ C (test (c) = FAIL --> ∀ c' ⊇ c ( test(C') != PASS ) )

この変形で,うまくいっている変更の部分集合だけを取り出しても,テストは失敗しない.∀c ⊆ C (test (c) = PASS --> ∀ c' ⊆ c ( test(C') != FAIL ) )(一時的に実行不能になっている場合もあるかもしれないが)

で,失敗してる構成同士を組み合わせても意味がなくて,∀c1, c2 ⊆ C ( test(c1) = FAIL ∧ test(c2) = FAIL --> test(c1∩c2) != PASS )

どんなテスト組み合わせでも未解決のテストが出ない状態を,[一貫した] 状態であるという.∀c ⊆ C ( test(c) != Unresolved )

…ということを利用すると,変更単位が自動で扱えるなら,自動で,どの変更がバグの原因かを示せる.

変更 8個あれば 4個ずつでテストを実行し,失敗したものについてはさらに2分してどちらが失敗しているか(あるいは両方失敗しているか),さらに失敗したものについて2分して……としていくことで,失敗するテストを判定する.成功したもの同士は今度はくっつけてテストを実行して,組み合わせることによって成功するものはどれか,というのを調べる.たとえば,1-4, 5-8 がそれぞれ成功したとして,3-8 がテスト失敗したなら 3 + 5-8 と 4+ 5-8 でテストして,……というように組み合わせを自動で探索する.

テストを効率よくグループ化するために,プログラムの変更に対してプログラムスライスをとって共有ノードがあるかどうか,といったことでその変更が相互に影響するかどうかを調べたらいいなぁ,なんてことを将来の課題として説明している.

お名前:
E-mail:
右の画像に書かれている文字列を入力してください:
コメント: