这是类似的,但与这篇文章,是我能找到的最接近的问题不一样。我甚至认为这个答案对线程中提出的问题不满意,更不用说TDD了。如果我在编写实际代码之前正在编写测试,那么如果我还不能运行我的代码,我又怎么能想出“特殊”情况呢?
我考虑的是神经网络和遗传规划这样的领域,虽然我可以避免对NN的随机方面进行单元测试,但遗传编程是一个完全不同的东西。在我的程序中,选择、重组、突变和配对算法都应该具有一定的统计特性以“正确”。注意,这不是“测试非单位”的情况,因为如果我的程序在每个级别上都没有正确的统计属性,那么我就有一个bug,尽管我的程序看起来工作得很好。我如何测试具有相似随机要求的进化算法或算法?
编辑:由于某些原因,这个问题暗示着这个在侧栏里没有正常工作,但我刚刚找到了。最上面的答案是关于Mocks的,但是在基因编程环境中,这种方法是如何工作的,在那里,分布本身需要进行测试?
发布于 2017-05-30 16:23:57
老实说,我不认为真正的TDD适合严重的随机程序。老实说,我不认为这对任何事情都是个好主意,但抛开这一点,你会让你的生活变得比它所需要的更艰难,在你允许自己编写任何代码之前,你必须通过测试才能完成GP。
不过,有几种方法可以进行良好的单元测试。有些东西是显而易见的测试类型,你可以为任何程序编写。我不会为此付出任何努力的。
对于随机算法,我将使用的一个具体技巧是找出我期望输出的分布,然后我将编写一个测试,它会多次运行,并检查结果的分布是否与我预期的相当接近。从你了解它们的方式来看,这些不是真正的单元测试。我的测试有时会失败,仅仅是因为不太可能发生的事情。我想要的是自信,而不是确定性。如果我的测试失败了,我会看实际的结果。他们看上去可能是合法地从我的发行的尾巴或不?也许我会再开几次这个套间,看看是否一切都恢复正常了。
当然,您也可以只修复RNG的种子,但是这会使您的测试变得非常脆弱,就好像您更改了算法的某些方面一样,需要从生成器中获得额外的示例,这之后的一切都会发生变化。因此,它最好用于测试算法中涉及代码数量很小的非常低级别的方面。
不过,大多数情况下,我过去所做的就是不要过于担心测试覆盖率作为衡量标准。我使用像前面提到的统计测试那样的高级测试,并尽我所能调试低级别的测试。有时候,我可以想出一个方法来写一个好的测试。其他时候,我在研究生院做了几次尝试调试新的随机优化算法:用打印语句来测试算法中的垃圾,打印出50页的输出,在实验室里把它粘到地板上,然后爬来爬去拿着一份打印出来的源代码,“好吧,它应该在这里生成一个随机数,如果这个数字小于0.3,它应该做blah blah...ok,它实际上生成了0.46721,所以让我们看看,它应该做这个instead...ok,看起来很好。”直到我确信我的算法正在做我想做的事情。
发布于 2017-06-23 23:47:29
TDD让您思考需要做什么,以及如何测试它。当你意识到设计必须改变中期开发,现在你的所有测试都需要调整时,这是一个痛苦的过程。
对于遗传算法来说,在一点熵发挥作用之前,还需要做大量的工作。你需要生成特工。您想要测试的是,您没有生成10亿个代理或零代理。你得给他们DNA。假设这是一个路径发现域,他们的DNA由N,S,E,W组成。你想要测试,以确保他们的DNA不包含除这4种选择以外的任何东西。您需要了解代理何时成功地导航路径/迷宫/目标/诸如此类。您想要测试程序在达到目标后是否停止了处理。首先编写测试会让您思考这些事情,并给出一个很好的任务列表。
当你想要你的框架成功地处理所有那些小特工们想要做的疯狂的事情时,遗传算法的固有的混乱性质就会发挥作用。你可以写出你能想到的测试,但你可以打赌,一旦特工们尝试了你没有想到的东西,你就会回来写更多的测试。比如..。走在地图的边缘。
从编写测试开始。那是TDD。但是,您不会停止编写测试,并且会意识到在中间会有大量的时间来响应代理破坏您的系统。记住,你不是在尝试测试你的遗传算法的紧急行为。检测终端条件应该是你的遗传算法包的一部分,测试它成功地检测到它应该找到的东西是测试的目标。
对于一般的随机算法,您尝试测试它可能产生的整个搜索空间,并模拟rand()函数,这样您就可以遍历整个搜索空间。如果搜索空间很广,不要假装你会捕捉到一切。
https://softwareengineering.stackexchange.com/questions/349853
复制相似问题