我们使用的是Twitter在Algebird中实现的HyperLogLog。在我们的系统中给出一个数字N和一个使用HyperLogLog估计逐渐增长的集合的当前大小并测试它是否大于或小于N的检查,如果我们调用HyperLogLog的代码是正确的,我们如何编写一个集成或系统测试来测试这个检查并且几乎可以保证通过呢?测试中的系统是不确定的,因为首先,它是多线程的。
我的第一个想法是,写一个对这个用例来说可靠的集成测试的正确方法是“降低我们的标准”。那么,什么是足够数量的项目(M)发布到一个端点,以确保HyperLogLog将估计项目总数大于N,概率为>= 0.999999?
还是有更好的方法?
标准的误差界是可配置的,但这并不能直接告诉我们我们可能偶尔会看到的最大误差界--这就是我所关心的,以避免在master上随机失败的CI构建导致浪费时间和拉扯头发!
我还担心,我们在测试中生成随机数据的方式可能不会在相关方面生成均匀分布的随机数据,这可能会对概率计算产生重大影响。
发布于 2016-11-05 09:35:33
让我们把这个问题分解一下。您要测试的主要行为有两种:
请注意,行为#2很容易在构建时使用单元测试测试,而不是使用集成测试。这是可取的,并将捕获大多数问题。
案例#1也可以分为三个案例:
A、当项数为0时;
B,当项目数量较少时(5、100或1000);
C,当项目数量很大时(数百万/数十亿)。
同样,案例A和B可以也应该在构建时使用单元测试进行测试。您应该根据您的应用程序决定可接受的误差范围,并让‘t断言估计值在这些范围内-选择HyperLogLog作为底层估计方法并不重要,测试应该将估计器视为黑盒。大致上,我会说10%的误差对于大多数目的来说是合理的,但这实际上取决于您的特定应用程序。这些界限应该代表您的应用程序所能承受的最差精度。例如,严重错误的计数器可能根本无法容忍任何估计错误,因此使用HyperLogLog会破坏单元测试。一个计数不同用户数量的计数器可能会有高达50%的估计误差--这取决于你。
因此,这给我们留下了最后一个用例测试,即HyperLogLog实现为大量项目提供了一个很好的估计。这是不可能在构建时测试的,实际上集成测试是可行的。然而,根据你对推特的HyperLogLog实现的信任程度,你可能会考虑不完全测试它-推特应该已经这样做了。这看起来像是打破了最佳实践,但考虑到可能与集成测试相关的开销,在您的案例中可能是值得的。
如果您选择编写集成测试,您将需要对生产中预期的流量进行建模,并从多个来源生成流量,因为您将生成数百万/数十亿的请求。您可以保存实际生产流量的样本并将其用于测试(可能是最准确的方法),或者计算出您的流量是什么样子并生成类似的测试流量。同样,应该根据应用程序选择误差范围,并且您应该能够在不破坏测试的情况下将估计方法替换为更好的方法。
https://stackoverflow.com/questions/40396415
复制相似问题