1

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

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

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: could not invoke action on current page报告的堆栈跟踪的匿名版本

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)
4

1 回答 1

1

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

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

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

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

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

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

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

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

于 2012-07-31T08:10:23.873 回答