誰か助けてください><
期待値とDBのテーブルを比較するようなテストなら、アサートもアノテーションでできるようにしようと考えた。
こんな感じで。
@TableAssert(names = "dept", pathname = "insert_expected.xml", queries = "select dname, deptno, loc from emp") @SetUpOperation(pathname = "dept.xml", value = DatabaseOperationType.DELETE_ALL) public void testTableAssert2() { insert(); }
XMLにある期待値とSELECT文の結果をアサートするイメージ。
いちおう、できたんだ。
コマンドラインから実行したり、main()メソッドで実行する分には。
eclipseプラグインで袋小路
でも、eclipseプラグインで実行するとダメ。
テーブルと期待値が違っていてアサートに失敗する場合でも、UIではPASSEDになっちゃう。
コンソールはこう出力される。
[DbUnitNGDatabaseOperation] [DEBUG] Database Operation is DELETE_ALL. [DbUnitNGDatabaseOperation] [DEBUG] Database Operation is DELETE_ALL. PASSED: testTableAssert PASSED: testTableAssert2 =============================================== sample Tests run: 2, Failures: 0, Skips: 0 =============================================== [DbUnitNGTestListener] [DEBUG] DbUnitNGTestListener#onFinish Test Suite ends. execute time : (865 ms) =============================================== DbUnitNG Total tests run: 2, Failures: 2, Skips: 0 ===============================================
スイート全体ではFailureになるけど、途中では PASSEDのまま。
これ、TestNGのeclipseプラグインがTestNGのRemoteClinetでテストを起動してるからだと思う。
RemoteClinetだと、プラグインでUIに表示するリスナーにはオブジェクトじゃなく文字列で通知が行く。
public void onTestSuccess(TestResultMessage trm) {
一方、僕がアノテーションでテーブルとアサートしているのは普通のリスナー。
public void onTestSuccess(ITestResult result) { TableAssert tableAssert = this.getAnnotation(result, TableAssert.class); if (tableAssert != null) { assertTable(tableAssert, result); } onTestFinishWhateverHappens(result); } protected void assertTable(TableAssert tableAssert, ITestResult result) { IDataSet actual = createQueryDataSet(tableAssert, result); IDataSet expected = toDataSet(tableAssert.pathname(), result); try { Assertion.assertEquals(expected, actual); } catch (Throwable e) { result.setStatus(ITestResult.FAILURE); result.setThrowable(e); } }
アサートのところで、テストのステータスをFAILUREに上書きしてるけど、RemoteClinetにはすでに文字列で通知が行ってるから、変更は反映されない。
だからプラグインのUIではPASSED、コンソールにはFAILUREと表示されてしまう。。。
これはさすがに使えないから、アノテーションでのアサートはあきらめないといけないかな。。。