当前位置: 首页 > 知识库问答 >
问题:

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

韦望
2023-03-14

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

我了解到,可以通过JUnitCore的RunListener类创建一个自定义侦听器来读取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

下面是JUnitjava.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个答案

太叔逸春
2023-03-14

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

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

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

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

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

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

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

事实似乎并非如此。我建议您使用大多数开发人员使用的工具(如IDE和maven),其中大多数问题都是为您处理的。(还有许多其他问题,你可能永远都不知道它为你带来了什么;)

 类似资料:
  • 我的测试方法中有多个断言(assertTrue),我想将断言失败传递给我的@AfterMethod,我的测试在该断言上失败,这样我就可以获得API测试失败的确切位置。有没有办法做到这一点?使用Rest assured,Maven&TestNG。

  • # 5.1 自定义报告是什么? {#51-自定义报告是什么?} 在进行网站分析的时候,通常需要关联多个维度进行分析, 同时根据不同组合维度,选取合适的衡量指标。 例如,衡量 广告流量 达成的事件数 或 不同来源流量的所使用客户端及其地域分布。 在默认报告中,系统提供了单个维度的分析视角。 而自定义报告则可实现关联不同分析维度,衡量站点数据表现。 示例如下: 维度1 维度2 维度3 衡量指标 广告维

  • 简介 此消息 用来接收 用户自定义TOPIC消息 发送过来的事件。 消息体 ChannelMessageBean 例子 Kotlin @Subscribe(threadMode = ThreadMode.MAIN) fun onReceiveCustomMessage(customEvent: ChannelMessageBean) { // TODO } ChannelMessageB

  • 我正在使用JUnit自动化功能测试。我遇到了一个问题:如果我遵循规则“每个测试方法一个(重要的)断言”,那么每个测试用例最终会有一堆6行测试方法(17个是迄今为止最大的数字)。如果我将它们全部放入一个测试方法中,我必须注释掉失败的断言,否则一半的测试永远不会启动。 我不喜欢第一种方式,因为它启动浏览器的次数太多,而且浏览器启动登录/注销似乎比测试运行本身更“昂贵”和耗时。 第二种方法也不好,因为它

  • 默认情况下,消息:此值无效。这是不够的。我正在向实体中的每个属性添加@Assert,以进行更具体的验证。 我将在表单顶部全局显示错误,而不是单独显示错误,以防在本次讨论中出现问题。 这是迄今为止我所知道的,但当我输入值“D44.33”时,表单仍然无效 如何覆盖默认的“类型”验证器?请注意,其他验证器(如GreaterThanOrEqual)的工作原理与预期相同,但就我而言,我无法让“类型”工作??