debugging 如果没有模糊测试,很难发现错误的函数的例子是什么?

cmssoen2  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(78)

我想为模糊测试和/或基于属性的测试提出一个激励性的例子或代码挑战。
我正在寻找的是一个简洁的情况下,这样的测试是最关键/必要的。
例如,理想情况下,它将需要足够的模糊运行,人类不太可能通过手动尝试随机单元测试或依靠直觉来发现bug。
奖金,如果:

  • 在TypeScript中(但不是什么大问题;我可以翻译)
  • 来自真实的/历史软件的示例

我试着问ChatGPT,但bug太明显了。我也试着用谷歌搜索了一下,发现了这个问题,但它仍然很明显,可能在几个单元测试之后也会暴露出来。我也考虑过做一些不完整的查找表(受Pentium FDIV bug的启发),但我不知道如何制作它,这样你就不能通过计算正确的查找表并进行比较来解决它。

bhmjp9jg

bhmjp9jg1#

在我看来,一个令人信服且易于理解的例子是素因子分解。看看这样一个算法的blog article on property-driven development

  • 完全披露:* 我是这篇文章的作者,也是所用PBT库的主要提交者。

考虑一下实现(抱歉是Java),因为它是在TDD使用属性的几个步骤之后产生的:

public static List<Integer> factorize(int number) {
    List<Integer> factors = new ArrayList<>();
    int candidate = 2;
    while (number >= candidate) {
        while (number % candidate != 0) {
            candidate++;
        }
        factors.add(candidate);
        number /= candidate;
    }
    return factors;
}

字符串
从算法的Angular 来看,factorize工作正常。一些缺点-例如。处理大数字时,潜在的整数溢出-只有当您使用通用属性将其设置为压力时才能发现:

@Property
void all_numbers_above_1_can_be_factorized(
        @ForAll @IntRange(min = 2, max = 10000) int number
) {
    List<Integer> factors = Primes.factorize(number);
    Integer product = factors.stream().reduce(1, (a, b) -> a * b);
    Assertions.assertThat(product).isEqualTo(number);
}


如果您开始增加max超过1_000_000并接近Integer.MAX_VALUE范围,则算法将运行很长时间或根本无法完成。这些失败的属性导致算法的改变,以处理整数的全范围的因式分解。快速运行到最大整数值的实现例如是:

public static List<Integer> factorize(int number) {
    List<Integer> factors = new ArrayList<>();
    int candidate = 2;
    while (number >= candidate) {
        while (number % candidate != 0) {
            if (Math.sqrt(number) < candidate) {
                candidate = number;
            } else {
                candidate++;
            }
        }
        factors.add(candidate);
        number /= candidate;
    }
    return factors;
}


在我了解PBT之前,我倾向于不测试这些东西;现在自然就来了。

相关问题