使用自定义消息报告JUnit断言失败

时间:2012-07-31 08:02:08

标签: java junit reporting

我一直在Eclipse中使用JUnit创建单元测试,JUnit的基本原理对我来说很清楚。 测试按原样运行,现在是时候找到报告失败测试的好方法了。我在Web上遇到的大多数示例都使用某种类型的构建系统,如Ant,Maven或Hudson,在构建项目的同时运行测试,但在构建过程中不需要这种集成。测试应该能够独立于构建系统运行。最后,这些系统只需从JUnit获取信息并将其放在一个漂亮的HTML布局中。

我了解到可以通过creating a custom listener via the RunListener class of JUnitCore读出JUnit信息,并使用“testFailure”方法处理失败。 在创建测试时,我总是为断言错误提供自定义消息。我的问题是这条消息没有出现在JUnit的故障跟踪中。相反,失败跟踪将显示“java.lang.Exception:无法调用*”。当我查看控制台时,我看到相同的堆栈跟踪,但下面还有一行前面有“引起:*”的行,在这里我看到了我的自定义错误消息。

Caused by: java.lang.AssertionError: <my custom error message>
    at *

由于我刚刚开始使用JUnit,我不知道这是否是JUnit的正常行为,或者我实现测试的方式有什么问题,我应该在故障跟踪中看到自定义消息吗? 我还注意到,当我在执行测试的方法中捕获断言错误时,我可以使用“error.getMessage()”来访问消息。因此,如果有必要,这将是一个解决方案,并且还允许我在报告中包含其他信息,这些信息在我捕获错误时(即网页的URL等)可访问,但是在每个断言周围放置一个try-catch块在我看来会打败它的目的。

正如我所说,我是单元测试的新手,但也是一般的Java开发,所以我很可能犯了一些愚蠢的错误。任何指针都非常欢迎!

更新2: 下面是控制台堆栈跟踪的匿名版本。也许这有助于澄清我的问题。

    java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at xxxxx.xxxxxxxxxxxx.xxxxxxxxx(xxxxxxxxxxx.java:103)
        at xxxxx.xxxxxxxxxxxxxx.xxxxxx(xxxxxxxxxxx.java:62)
        at junit.framework.TestCase.runBare(TestCase.java:134)
        at junit.framework.TestResult$1.protect(TestResult.java:110)
        at junit.framework.TestResult.runProtected(TestResult.java:128)
        at junit.framework.TestResult.run(TestResult.java:113)
        at junit.framework.TestCase.run(TestCase.java:124)
        at xxxxx.xxxxxxxxxxxx.xxxxx(xxxxxxxxxxxx.java:90)
        at junit.framework.TestSuite.runTest(TestSuite.java:243)
        at junit.framework.TestSuite.run(TestSuite.java:238)
        at xxxxx.xxxxxxxxxxxxxxxxxxxx.xxxx(xxxxxxxxxxxxxxxx.java:87)
        at junit.framework.TestSuite.runTest(TestSuite.java:243)
        at junit.framework.TestSuite.run(TestSuite.java:238)
        at xxxxx.xxxxxxxxxxxxxxxxxxxxxx.xxxxx(xxxxxxxxxxxxxx.java:87)
        at junit.framework.TestSuite.runTest(TestSuite.java:243)
        at junit.framework.TestSuite.run(TestSuite.java:238)
        at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: java.lang.AssertionError: <xx my custom message xx>.
        at xxx.xxxxxxxx.xxxxxxxxxxxxxx(xxxxxxxx.java:100)
        ... 27 more

下面是JUnit报告的堆栈跟踪的匿名版本 java.lang.Exception:无法调用当前页面上的操作

java.lang.Exception: could not invoke action <xx action name xxx> on current page class xxxx.xxxxxxx: [Ljava.lang.StackTraceElement;@71d382ab
at xxxxx.xxxxxxxxxxxxxxxxx.xxxxx(xxxxxxxxxxxxxxxxxxxx.java:65)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at xxxxx.xxxxxxxxxxxxxxxxx.xxxxx(xxxxxxxxxxxxxxxxxxxx.java:90)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at xxxxx.xxxxxxxxxxxxxxxxx.xxxxx(xxxxxxxxxxxxxxxxxxxx.java:87)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at xxxxx.xxxxxxxxxxxxxxxxx.xxxxx(xxxxxxxxxxxxxxxxxxxx.java:87)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
at xxxxx.<xx class that initiates the RunListener xx>.main(<xx class that initiates the RunListener xx>.java:11)

1 个答案:

答案 0 :(得分:1)

  

测试应该能够独立于构建系统运行。

即使您使用构建系统,测试也将是独立的。它的目的是让你的生活从长远来看更容易,所以我建议你考虑使用一个。我建议起初我不喜欢的maven,因为它告诉你如何布局像目录这样的东西,但现在我可以看到这让你的生活更轻松。

  

当我查看控制台时,我看到相同的堆栈跟踪,但下面还有一行前面有“引起:*”的行,在这里我看到了我的自定义错误消息。

大多数工具会将其删除,因此您只能看到所需内容。例如在大多数IDE中,您可以单击堆栈跟踪并导航到导致问题的代码行。如果您使用maven,IDE将与您的maven配置同步,以便它可以找到负责的代码。

  

我还注意到,当我在执行测试的方法中捕获断言错误时,我可以使用“error.getMessage()”来访问消息。

如果使用maven和/或IDE,则无需执行任何操作。

  

我很可能犯了一些愚蠢的错误。

似乎并非如此。我建议你使用大多数开发人员使用的工具(比如IDE和maven),大部分问题都是为你处理的。 (还有许多其他问题,你可能永远不会知道它为你做的;)