当前位置:  开发笔记 > 人工智能 > 正文

如何进行不确定性的单元测试?

如何解决《如何进行不确定性的单元测试?》经验,为你挑选了4个好方法。

我们有几种不同的优化算法,可以为每次运行产生不同的结果.例如,优化的目标可以是找到函数的最小值,其中0是全局最小值.优化运行返回如下数据:

[0.1, 0.1321, 0.0921, 0.012, 0.4]

这与全球最小值非常接近,所以这没关系.我们的第一种方法是选择一个阈值,如果结果发生得太高,让单元测试失败.不幸的是,这根本不起作用:结果似乎有一个高斯分布,因此,虽然不太可能,但即使算法仍然很好而且我们运气不好,测试也会不时发生.

那么,我该如何正确测试呢?我想这里需要相当多的统计数据.同样重要的是测试仍然很快,只需让测试运行几百次,然后取平均值就太慢了.

以下是一些进一步的说明:

例如,我有一个算法将Circle拟合成一组点.它非常快,但并不总能产生相同的结果.我想写一个单元测试,以保证在大多数情况下它足够好.

不幸的是我无法为随机数生成器选择固定种子,因为我不想测试算法是否产生与以前完全相同的结果,但我想测试类似"有90%确定性我得到0.1或者0.1的结果"更好".

John D. Cook.. 15

听起来你的优化器需要两种测试:

    测试算法的整体有效性

    测试算法实现的完整性

由于算法涉及随机化,(1)难以进行单元测试.任何随机过程的测试都会在某些时间内失败.您需要了解一些统计信息才能了解它应该失败的频率.有很多方法可以在测试的严格程度和失败的频率之间进行权衡.

但是有一些方法可以为(2)编写单元测试.例如,您可以在运行单元测试之前将种子重置为特定值.然后输出是确定性的.这不会让你评估算法的平均有效性,但那是(1).这样的测试可以作为一个旅程线:如果有人在维护期间将错误引入代码中,确定性单元测试可能会捕获该错误.

可能还有其他东西可以进行单元测试.例如,无论随机部分发生什么,也许您的算法可以保证在一定范围内返回值.也许某些价值应该总是积极的等等.

更新:我在Beautiful Testing中写了一篇关于这个问题的章节.请参阅第10章:测试随机数生成器.



1> John D. Cook..:

听起来你的优化器需要两种测试:

    测试算法的整体有效性

    测试算法实现的完整性

由于算法涉及随机化,(1)难以进行单元测试.任何随机过程的测试都会在某些时间内失败.您需要了解一些统计信息才能了解它应该失败的频率.有很多方法可以在测试的严格程度和失败的频率之间进行权衡.

但是有一些方法可以为(2)编写单元测试.例如,您可以在运行单元测试之前将种子重置为特定值.然后输出是确定性的.这不会让你评估算法的平均有效性,但那是(1).这样的测试可以作为一个旅程线:如果有人在维护期间将错误引入代码中,确定性单元测试可能会捕获该错误.

可能还有其他东西可以进行单元测试.例如,无论随机部分发生什么,也许您的算法可以保证在一定范围内返回值.也许某些价值应该总是积极的等等.

更新:我在Beautiful Testing中写了一篇关于这个问题的章节.请参阅第10章:测试随机数生成器.



2> Matthew Brub..:

单元测试不应该具有未知的通过/未通过状态.如果您的算法在多次使用相同输入运行时返回不同的值,那么您可能在算法中做了一些棘手的事情.

我将采用5种优化算法中的每一种并测试它们以确保给定一组输入x,每次都得到y的优化值.

编辑:要解决系统的随机组件,您可以引入传递种子的功能,以便使用随机数生成器,或者您可以使用模拟库(ala RhinoMocks)强制它使用特定的数字要求RNG提供随机数.


我认为对一组特定的"随机"数字进行定制测试比看到它是否在大多数情况下使用*真实*PRNG做得更好更脆弱.是的,重复性通常很好 - 但不是不惜一切代价.

3> Rasmus Faber..:

您的算法可能有一个随机组件.把它控制住.

你也可以

    允许调用者为随机数生成器选择种子.然后在测试中使用硬编码的种子.

    让呼叫者提供随机数发生器.然后在测试中使用伪随机数生成器.

第二个选项可能是最好的,因为这样可以更容易地推断出算法的正确结果.

在单元测试算法时,您要验证的是您已正确实现了算法.不是算法是否按预期执行.单元测试不应将待测代码视为黑盒子.

您可能需要有一个单独的"性能"测试至比较不同的算法如何运行(以及他们是否实际工作),但你的单元测试是用于测试你的实现算法.

例如,在实现Foo-Bar-Baz优化算法(TM)时,您可能不小心写了x:= x/2而不是x:= x/3.这可能意味着算法工作得更慢,但仍然找到相同的算法.您需要进行白盒测试才能找到这样的错误.

编辑:

不幸的是我无法为随机数生成器选择固定种子,因为我不想测试算法是否产生与以前完全相同的结果,但我想测试类似"有90%确定性我得到0.1或者0.1的结果"更好".

我看不出任何方法可以进行自动验证和随机测试.特别是如果你想有机会将真实误差与统计噪声区分开来.

如果你想测试"有90%的确定性我得到0.1或更好的结果",我建议如下:

double expectedResult = ...;
double resultMargin = 0.1;
int successes = 0;
for(int i=0;i<100;i++){
  int randomSeed = i;
  double result = optimizer.Optimize(randomSeed);
  if(Math.Abs(result, expectedResult)

(请注意,此测试是确定性的).



4> Jon Skeet..:

让测试运行,如果其中任何一个失败,重新运行这些测试 50次,看看他们失败的时间比例.(当然是以自动方式.)

推荐阅读
重庆制造漫画社
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有