我们有一个庞大而复杂的函数,需要确定性。它是我们公司的主力之一,涵盖了大量代码。由于 python 的字典迭代器,此代码通常变得不确定。这种情况发生过很多次,追查起来非常困难,而且往往没有立即引起注意。我们想编写一个自动化测试来检测不确定性,但我不确定该怎么做。
我们已经尝试在循环中运行该函数,并且测试结果始终相同,但有时,即使该函数是不确定的,该函数也会通过此测试,因为字典迭代器。
有没有办法编写自动化测试来捕获这种错误?
也许有一种方法可以破解 python 的字典,以便在该测试期间迭代器是随机的而不是任意的?这样重复调用函数会更有可能发散吗?这似乎是一个相当复杂的方法,但我想不出任何其他方法。
编辑:
我们目前使用的是 Python 2.7。
我们对各种子模块进行了单元测试,但是由于 dict 顺序的任意性但一致的性质,它们通常不会暴露不确定性。
另外,也许不确定性并不是描述这个问题的正确方式。此函数采用 {id : data},但是 id 的值不应影响代码的结果,但由于 python dict 排序,它有时会影响。也许最好的测试方法是用随机值替换 ID,并检查在使用不同 ID 多次运行后输出是否相同。
最佳答案
如果想随机化哈希种子,可以给python指定-R
标志:
-R : use a pseudo-random salt to make hash() values of various types be
unpredictable between separate invocations of the interpreter, as
a defense against denial-of-service attacks
啦啦啦
~$ python -c "print {y:x for x,y in enumerate('foobar')}"
{'a': 4, 'r': 5, 'b': 3, 'o': 2, 'f': 0} #it will always be this
~$ python -R -c "print {y:x for x,y in enumerate('foobar')}"
{'a': 4, 'b': 3, 'r': 5, 'f': 0, 'o': 2}
~$ python -R -c "print {y:x for x,y in enumerate('foobar')}"
{'a': 4, 'b': 3, 'r': 5, 'o': 2, 'f': 0}
~$ python -R -c "print {y:x for x,y in enumerate('foobar')}"
{'f': 0, 'o': 2, 'b': 3, 'r': 5, 'a': 4}
~$ python -R -c "print {y:x for x,y in enumerate('foobar')}"
{'r': 5, 'f': 0, 'o': 2, 'a': 4, 'b': 3}
请注意,此行为是 python 3.3 中的默认行为。
关于python - 测试 python 函数的非确定性行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21918667/