使用HyperLogLog对代码进行可靠的集成测试?

时间:2016-11-03 07:59:21

标签: integration-testing approximation hyperloglog

我们正在使用Twitter在Algebird中实现HyperLogLog。给定N和我们的系统中的检查,使用HyperLogLog估计逐渐增长的集合的当前大小并测试它是否多于或少于N,我们如何编写测试此检查的集成或系统测试,如果我们调用HyperLogLog的代码是正确的,几乎可以保证通过?被测系统是非确定性的,因为,一方面,它是多线程的。

我的第一个想法是,为这个用例编写可靠的集成测试的正确方法是降低我们的标准"。那么什么是足够数量的项目(M)发布到端点,以确保HyperLogLog将估计项目的总数大于N,概率,例如,> = 0.999999?

或者有更好的方法吗?

标准错误界限是可配置的,但是它并没有直接告诉我们偶尔可能看到的最大错误界限 - 这是我关心的,以避免在master上出现随机失败的CI构建造成浪费时间和拔毛!

我还担心我们在测试中生成随机数据的方式可能无法在相关方面生成均匀分布的随机数据,这可能会对概率计算产生重大影响。

1 个答案:

答案 0 :(得分:2)

让我们稍微打破一下。您需要测试两种主要行为:

  1. Twitter HyperLogLog实现正确执行,即它可以很好地估计项目数。

  2. 您的代码使用HyperLogLog结构(例如计数器)会在适当时增加它们。

  3. 请注意,行为#2在构建时使用单元测试很容易测试,而不是使用集成测试。这是最好的,并且可以解决大多数问题。

    案例#1也可分为三种情况:

    A,当项目数为0时;

    B,当项目数量很少(5,100或1000)时;

    C,当项目数量很大(数百万/十亿)时。

    同样,案例A和B可以并且应该在构建时使用单元测试进行测试。您应根据您的应用决定可接受的误差范围,并让UT声明估计值在这些范围内 - 您选择HyperLogLog作为基础估算方法并不重要,测试应将估算器视为黑盒子。作为一个棒球场,我说10%的错误在大多数情况下是合理的,但这完全取决于您的特定应用。这些界限应该代表您的应用程序可以忍受的最差精度。例如,关键错误的计数器可能根本无法存在任何估计错误,因此使用HyperLogLog会破坏单元测试。针对不同用户数量的计数器可能会产生高达50%的估计误差 - 这取决于您。

    因此,我们留下了最后一个案例 - 测试HyperLogLog实现对大量项目进行了很好的估计。这不可能在构建时进行测试,实际上集成测试是可行的方法。但是,根据您对Twitter的HyperLogLog实施的信任程度,您可能会考虑完全没有测试 - Twitter应该已经这样做了。这似乎是对最佳实践的突破,但考虑到可能与集成测试相关的开销,在您的情况下可能是值得的。

    如果您选择编写集成测试,则需要对生产中期望的流量进行建模并从多个来源生成,因为您将产生数百万/数十亿的请求。您可以保存实际生产流量的样本并将其用于测试(可能是最准确的方法),或者计算出流量的样子并生成类似的测试流量。同样,应根据应用选择误差范围,并且您应该能够在不破坏测试的情况下将估算方法换成更好的方法。