読者です 読者をやめる 読者になる 読者になる

ゲンゾウ用ポストイット

Java、Groovy、Linux関連の備忘録

Power Assertを試してみる

Groovy1.7から導入されたPower Assertを試してみた。

これによりassertによる検証エラーが発生した場合の式の状態が詳細に表示され、問題の原因を素早く特定できる。

まずは実行

assertを利用した簡単なコードを記述する。

test.groovy
#!/usr/bin/env groovy
def list = [1, 3, 4, 5, 2]
assert 5 == list.max() - 1

ほいで実行。

$ chmod 750 test.groovy
$ ./test.groovy
Caught: Assertion failed: 

assert 5 == list.max() - 1
         |  |    |     |
         |  |    5     4
         |  [1, 3, 4, 5, 2]
         false

	at test.run(test.groovy:3)

これはわかりやすい。ただ、いくつか疑問点が浮かんできた。

javaコマンドから実行した場合は?

groovycでコンパイルしたクラスファイルをjavaコマンドで呼び出してもちゃんと表示されるのか?
と思ったので試してみた。

$ groovyc test.groovy
$ java -cp $GROOVY_HOME/embeddable/groovy-all-1.7.0.jar:. test
Exception in thread "main" Assertion failed: 

assert 5 == list.max() - 1
         |  |    |     |
         |  |    5     4
         |  [1, 3, 4, 5, 2]
         false

	at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:378)
	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.assertFailed(ScriptBytecodeAdapter.java:662)
	at test.run(test.groovy:3)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1058)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:886)
	at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:743)
	at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:726)
	at org.codehaus.groovy.runtime.InvokerHelper.runScript(InvokerHelper.java:386)
	at org.codehaus.groovy.runtime.InvokerHelper$runScript.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:129)
	at test.main(test.groovy)

groovyコマンドで実行した場合と表示される例外文の量に違いはあるが、Power Assertの解析結果はちゃんと表示されている。javaにも欲しい。

コードに直接既述してるからじゃね?

ということでコマンドライン引数からもらった値を利用したコードに書き換える。

test2.groovy
#!/usr/bin/env groovy
def list = args.collect{ it.toInteger() }
assert 5 == list.max() - 1

ほいで実行。

$ groovyc test2.groovy 
$ java -cp $GROOVY_HOME/embeddable/groovy-all-1.7.0.jar:. test2 3 7 8 1 4
Exception in thread "main" Assertion failed: 

assert 5 == list.max() - 1
         |  |    |     |
         |  |    8     7
         |  [3, 7, 8, 1, 4]
         false

	at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:378)
	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.assertFailed(ScriptBytecodeAdapter.java:662)
	at test2.run(test2.groovy:3)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1058)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:886)
	at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:743)
	at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:726)
	at org.codehaus.groovy.runtime.InvokerHelper.runScript(InvokerHelper.java:386)
	at org.codehaus.groovy.runtime.InvokerHelper$runScript.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:129)
	at test2.main(test2.groovy)

これはデバッグ時だけでなく、本番稼働時の不具合原因時に貢献してくれるはず。

2010/01/23 追記

しくみはid:uehajさんのBlogや、コメントのPowerAssertを参考に。
uehaj's blog

広告を非表示にする