AssertionのAssertion(未公開)
こっち方面から離れ気味です。
最近はアンチパターンについて主にネットで調べておりました。
そして、下記リンクのページを見つけてインスパイアされたのが今回のネタです。
(2004年のエントリなので新鮮ではないです。)
JUnitが全てグリーン、Coverageが全て100%だったとしても、JUnitのテストメソッドにassertXXXが全く含まれていなかったら意味が無いですね。
実際、それって検出できないよね?と以前から思ってはいました。
ちょっと調べたところでは、目的のものが見つからなかったので、実験的に作ってみました。
いまのところ本体は未完成。将来、ある程度まで完成したら公開するかも知れません。
ライブラリは、この2つを使ってみます。
- Apache Commons BCEL(Apache License v2.0)
- javaparser - Java 1.5 Parser and AST(LGPL)
処理イメージ。
- .javaもしくは.classを解析し、テストメソッドを抽出
- テストメソッドに含まれるassertXXX呼び出しをリストにする
- 以下を可能な限り解析
- actualに指定されたコードがテスト対象メソッドの呼び出しかどうかを調べる
- テストメソッド名とテスト対象メソッド名が似ているかどうかを調べる
- 以下を可能な限り解析
自然言語でも何て書けば良いか分からない体たらく。
このレベルでassertXXXの個数が分かるだけでもマシ、という程度の気持ちです。
- テストコード
TestCaseParser.Result[] a = {TestCaseParser.parse(ju3filepath), TestCaseParser.parse(ju4filepath)}; for (TestCaseParser.Result result : a) { for (Method method : result.getTestMethods()) { final String name = String.format("%s#%s", result.getClassName(), method.getName()); TestMethodParser.Result parser = TestMethodParser.parse(method); List<AssertInfo> infos = parser.getAssertInfos(); // assertXXXが少なくともn個以上あることを表明 assertMinCount("method [" + name + "] assertion count: min %d, but was %d", 1, infos.size()); for (AssertInfo info : infos) { // actualに適切なテスト対象メソッドの実行が指定されていることを表明 if (!info.isValidActual()) { failWithFormat("invalid actual value [%s] in method %s", info.actualCode, name); } } } }
テストコードがちょっと複雑になるだけで対応できなくなります。
合格させるためというより、怪しいコードを絞り込むのに使うのでしょう。
あとはせめてVisitorで任意の解析が追加出来るようにするくらいにはしておきたいですね。