【问题标题】:Assuming a high probability case during testing在测试期间假设一个高概率案例
【发布时间】:2015-11-01 09:05:59
【问题描述】:

当我遇到一个有趣的场景时,我最近开始向我所有的旧项目添加单元测试以提高可维护性

一个这样的例子是UUID 类,它是randomUUID() 方法。给定特定测试依赖于两个随机生成的 UUID 不同的场景,为这种情况添加假设检查是否过度/不必要,例如:

UUID firstUID = UUID.randomUUID();
UUID secondUID = UUID.randomUUID();

// Is this test excessive
assumeFalse(firstUID.equals(secondUID));

// Rest of test here

虽然从包括here 在内的许多地方都可以看出,UUID 冲突实际上是不可能的,但这种方法的 javadoc 并未声称它是:

用于检索类型 4(伪随机生成)UUID 的静态工厂。 UUID 是使用强加密伪随机数生成器生成的。

子句cryptographically strong pseudo random number generator 是有保证的,但没有明确声明生成的 UUID 的唯一性。这意味着 randomUUID() 的潜在未来实现可能会改变它的实现,从而在不破坏方法声明的合同的情况下更有可能发生冲突。

虽然这种情况似乎很孤立,但它确实会不时出现,尤其是在处理随机数生成(也包括质数生成)时。从我的角度来看,添加假设子句对性能影响不大,所以我把它留在了。但总的来说,在单元测试期间添加高概率(实际上几乎不可能失败)假设是一个好主意吗?还是他们过分了?为了更进一步,在为它们编写实际假设条款之前,是否有关于给定假设必须失败的可能性的指南?我猜assumeFalse(the world is ending) 会被认为是过度的。

P.S:规范下的实际代码使用我不知道但保证唯一性的第三方 UUID 生成系统。由于这种情况是对原始 API 的扩展,因此我将其 UUID 生成替换为虚拟 randomUUID(),这样该假设仅适用于测试(实际代码为 100%)。

另一种方法是编写能够保证条件的系统(而不仅仅是假设它们的高概率),尽管我发现这对于小型测试来说太过分了。

【问题讨论】:

    标签: java unit-testing junit automated-tests


    【解决方案1】:

    嗯,整个事情可能几乎都是基于意见的,但我在这里看到的主要问题不是性能损失,而是您正在测试随机的东西(在最坏的情况下)有时会发生有时不会发生。那你怎么办呢?重新运行测试将提供不同的结果。那么这对你有什么帮助呢?你肯定会意识到它会发生,好吧,但是知道这不应该是实验的结果(单元测试是错误的工具),而是阅读文档和代码的结果。

    所以我认为你在这里工作的级别是错误的:你应该找出(ONCE)如果这是可能的,决定这种情况是否可以接受,如何处理这种情况,然后测试你处理这个问题的代码。 (如果你需要测试你正在使用的框架,那么无论如何你都在使用错误的框架。)

    【讨论】:

      【解决方案2】:

      我不会使用假设假,而是将 secondUID 的生成放在 while 循环中。重新生成 secondUID,直到它不再等于 firstUID。这样,当 firstUID 等于 secondUID 时,您就不会因为极小的机会而导致测试失败。

      【讨论】:

        猜你喜欢
        • 2012-11-17
        • 2014-03-31
        • 2010-10-13
        • 2021-04-29
        • 2019-09-12
        • 1970-01-01
        • 2012-06-07
        • 2017-10-29
        • 2012-07-18
        相关资源
        最近更新 更多