そろそろPower Assertについてひとこと言っておくか
タイトルはもちろん釣りで・・・はない!
ちょっと真面目に、Power Assertについて意見を述べたいのです。
そもそもPower Assertって何?
てきとーに説明すると、
普通の比較演算子で普通にassert書けば、失敗時に各部分式の値を表示してくれる
ようなものです。 Groovy製のテスティングフレームワークであるSpockがおそらく本家大本です((要出典。こういう系の発想は割と昔からあったし、Spock以前に実装例がありそうな気がする。そもそも、Spockは最初からPower Assert持ってたのかも調べないといけない。ちなみに、式木を弄ってAssertを組み立てる、というものであれば(PowerAssertよりも情報量は少なくなるものだけど)、自分の知る限りだと2009年6月にこんな記事があります。 http://themechanicalbride.blogspot.jp/2009/06/better-unit-tests-with-testassert-for.html まずはこの時点でのSpockの実装を確認せねば・・・))。
Groovyでこう書くと、
def xs = [0,1,2,3,4] assert 1 == xs.min()
こうなります。
Exception thrown 10 02, 2013 2:57:46 午後 org.codehaus.groovy.runtime.StackTraceUtils sanitize WARNING: Sanitizing stacktrace: Assertion failed: assert 1 == xs.min() | | | | | 0 | [0, 1, 2, 3, 4] false at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:399) 以下略
おお!値がどうなったか一目瞭然ですね!
Power Assertをユニットテストに使う
どこがどうなったってアサーションに失敗したのかが分かりやすいため、 これをユニットテストのアサーションとして採用する流れがあります。
こんな感じですね。
import groovy.transform.Canonical @Canonical class User { def name def age } def a = new User("hoge", 10) assert a == new User("hoge", 20)
Exception thrown 10 02, 2013 3:05:37 午後 org.codehaus.groovy.runtime.StackTraceUtils sanitize WARNING: Sanitizing stacktrace: Assertion failed: assert a == new User("hoge", 20) | | | | | User(hoge, 20) | false User(hoge, 10) 略
Groovy知らなくても、何が起こっているのかはよくわかると思います。
何が起こっているかは、確かに一目瞭然なのですが・・・
俺たちが欲しかった情報はなんだ?
ユニットテストにおいて、最も欲しいのは「どこがどうなっているか」ではなく、 「どこがどう違っているか」じゃないですかね。
「どこがどうなっているか」だけ渡されても、「どこがどう違っているか」は目視で確認しなけりゃならんのです。 だるいのです。 先の例くらいならまだマシですけど、長い文字列とかだと探すの大変です。
import groovy.transform.Canonical @Canonical class SomeData { String str int i }
Assertion failed: assert a == new SomeData("very long long long string", 20) | | | | | SomeData(very long long long string, 20) | false SomeData(very long long long sting, 19)
19に釣られて、very long long long stringとvery long long long stingの違いを見抜けなくて(本来)無駄なRedになってしまっても、それは仕方がないことですよね。
本当に欲しい情報って、例えばこんなものじゃないですかね?
Assertion failed: equality check is failed. difference: - SomeData.str: ["...st(-)ing", "...st(r)ing"] - SomeData.i: ["(19)", "(20)"]
この下に、どこがどうなったか情報があったら重宝はすると思います。 が、それが最初じゃないでしょう、と言いたいのです。
じゃぁお前が実装しろよ
ここで、「なので実装しました!」とか言えたら超かっちょいいんですけど、
(社内用テスティングフレームワークとして)作りかけて止まっちゃってます・・・
ちょっと別の色々(LangExtとか)に時間が取られちゃってまして・・・
でも、自分が欲しいのは正直こういう形の情報なんですよね。 PowerAssert的な情報は、あると便利だけどそれだけあっても辛いのです。
なので、このエントリの意見に同意してくれて、時間ある人は是非作ってみてほしいんですよね。 Power Assertに「欲しかったのはお前じゃないんだ!」を突き付けたい!!!