【问题标题】:What is the recommended way to log data that caused errors in JUnit?记录导致 JUnit 错误的数据的推荐方法是什么?
【发布时间】:2009-02-14 16:39:26
【问题描述】:

我对 JUnit 比较陌生,今天我正在编写一些我的第一个测试。对于某些特定方法,我想传递随机值(所有这些值都在正确的范围内)。如果该方法因任何原因失败,我想知道是哪个值导致它失败。那么推荐的方法是什么?

(或者在 JUnit 测试中使用随机值是不是很糟糕?)

【问题讨论】:

    标签: java unit-testing logging junit


    【解决方案1】:

    如果您真的想使用随机值,只需将使用中的值放在断言方法的文本部分即可。然后,如果断言被破坏,输入值就会出现,您可以调查它出现问题的原因。

    这是Fuzz Testing,它是一种强大的技术,但在您没有可用源代码或测试具有复杂内部状态和多个交互的系统时最有用。

    对您来说更有用的测试类型可能是white box testing,其中有意选择测试输入以涵盖您可能获得的各种输入类别。 JTest 似乎是 java 中的自动化工具。 MS Research 为 c# 提供 PEX)。

    如果手动完成,只需使用覆盖工具并验证您是否覆盖了相关路径通常就足够了,尽管自动化工具提供的边界情况通常很有指导意义。

    【讨论】:

      【解决方案2】:

      您可以尝试使用:http://www.openfuture.de/Log4Unit/ 进行日志记录,我建议不要对单元测试使用随机值,因为它们应该重复。如果你想测试很多值,只需使用 for 循环和对索引值的一些修改,这很容易重复。

      如果您仔细想想,确实没有任何情况下使用随机值比“硬编码”值更有益。如果您想在一个值范围内获得良好的分布,您可以使用函数或使用具有固定种子的随机值(以获得相同的数字)。

      如果测试失败,您希望能够修复它并再次运行测试。这就是单元测试中随机数的问题。

      【讨论】:

      • +1。测试应该是“可重复的”......使用一组不同的值来测试边界条件...... RowTest 应该满足您的需求。
      • 谢谢。但是,只要正确使用随机值,恕我直言,使用随机值进行测试并不是那么糟糕。在检查了边界和一些中间值之后,随机测试可以很好地揭示我在创建测试时没有想到的其他特殊情况。 ...
      • 通过记录种子值,可以重现错误,从而修复。否则,错误可能会溜走很长时间。 (这让我想起了二进制搜索实现错误:))。你怎么看?
      • 听起来很麻烦。根据您的逻辑,您想找到我的“意外”错误。如果您使用一个固定的随机值并测试 10000 个值,但每次都是相同的值,它会同样好且可重复,而无需查看日志文件。
      • 单元测试中的日志文件更多是用来记录有效的东西,如果你想要一些额外的信息,因为在这些情况下,JUnit 不会给你任何东西。
      【解决方案3】:

      只需在断言的“诊断消息”参数中报告实际值和预期值。这是 JUnit 测试的常见做法,“帮助”断言方法默认情况下倾向于这样做,例如assertEquals 会说类似“预期 6 并得到 7”。

      随机值是可以的,只要你能保证随机范围对被测代码构成一个等价类

      【讨论】:

      • 谢谢。这就是我一直在寻找的。​​span>
      【解决方案4】:

      您是否尝试过使用 JUnit 4.4+ 中的“assertThat”方法和 Hamcrest 匹配器?查看 README [1] 并搜索“assertThat”。

      我已经非常喜欢代码更具语义化的外观,并且失败消息的信息量也更多。

      [1]http://junit.sourceforge.net/README.html

      【讨论】:

      • 谢谢。这确实是有用的信息。我没有尝试这些方法,因为我使用的是 JUnit 4.3.1(它与 Eclipse Ganymede 捆绑在一起)。我一定会尝试新版本。
      【解决方案5】:

      我建议parameterized test cases。所以你可以使用随机值(在 Data 方法中),如果任何方法失败,它会在你的跑步者中“记录”。

      【讨论】:

        【解决方案6】:

        如果您的单元测试因任何原因失败,您将在测试运行程序中看到一个红色的交通灯。测试运行程序还将向您显示哪个测试方法失败,并且测试运行程序的日志会报告更多详细信息(例如转储的堆栈跟踪)。调查该错误并更正它,您的测试将永远不会再次失败,除非您破坏了代码。

        因此,我认为没有必要记录异常。您应该立即修复任何错误(红灯)。

        如果您不能保证生成的这些值没有错误,那么使用随机值可能会非常危险。检查边界条件可能更有用。

        【讨论】:

        • 谢谢,但我实际上并不是在尝试记录异常,而是在尝试创建可重现的伪随机测试用例。检查我对@Kent 答案的评论,或@ShuggyCoUk 答案中的模糊测试链接。
        【解决方案7】:

        您可以通过向随机数生成器提供常量种子来获得可重复的随机值。在 Java 中创建一个带有固定值的 java.util.Random,并将其作为构造函数参数传递给类(依赖注入)。像这样:

        new ClassUnderTest(new Random(123L));
        

        根据您要测试的内容,您还可以将随机值的生成与它们的使用分开。如果您有 X 类,它采用 1 到 10 范围内的随机值,那么您可以通过将边缘值 1 和 10 以及中间值(例如 4)传递给它来测试它。然后您需要对这些的生产者进行另一个测试随机值。例如,给它一个带有固定种子的 java.util.Random 并生成 100 个值,并检查它们是否都在允许的范围内。

        【讨论】:

          猜你喜欢
          • 2010-11-08
          • 2020-06-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多