【发布时间】:2009-10-21 04:39:09
【问题描述】:
我已经实现了 FIFO 信号量,但现在我需要一种方法来测试/证明它们是否正常工作。一个简单的测试是创建一些线程尝试在信号量上等待,然后打印带有数字的消息,如果数字按顺序排列,则它应该是 FIFO,但这不足以证明这一点,因为该顺序可能有偶然发生的。因此,我需要一种更好的测试方法。
如有必要,也可以使用锁或条件变量。
谢谢
【问题讨论】:
我已经实现了 FIFO 信号量,但现在我需要一种方法来测试/证明它们是否正常工作。一个简单的测试是创建一些线程尝试在信号量上等待,然后打印带有数字的消息,如果数字按顺序排列,则它应该是 FIFO,但这不足以证明这一点,因为该顺序可能有偶然发生的。因此,我需要一种更好的测试方法。
如有必要,也可以使用锁或条件变量。
谢谢
【问题讨论】:
你用你的句子“但这不足以证明它,因为这个顺序可能是偶然发生的”在某种程度上是一个已知的困境。
1) 即使您有规范,也无法确保该规范符合您的意图。为了说明这一点,我将以"the limit of correctness" 为例。让我们考虑一个分解函数的规范:
计算 A 和 B 例如 A * B = C
但这还不够,因为您可以有一个返回 A=1 和 B=C 的实现。添加A,B != 1 仍然可以导致A=-1 和B=-C,因此唯一正确的规范必须声明A,B>1。这只是为了说明编写符合真实意图的规范有多复杂。
2) 即使已经证明算法,仍然不意味着实现在实践中是正确的。最好用 Donald Knuth 的 this quote 来说明这一点:
注意上述代码中的错误;我 只证明是对的,没试过 它。
3) 测试只能揭示bug的存在,而不是它们的缺席。这句话可以追溯到Dijkstra:
测试可以用来展示 存在错误但从不显示 他们的缺席。
结论:你注定要失败,你永远不会 100% 确定你的代码按照它的意图是正确的!但事情并没有那么糟糕。对代码有很高的信心通常就足够了。例如,如果使用多个线程对您来说仍然不够,您可以决定也使用模糊测试,以使测试执行更加随机化。如果你的测试总是通过,那么你可以确信你的代码是好的。
【讨论】:
因为这个顺序可能是偶然发生的。
您可以运行几次测试,例如10,并测试每次订单是否正确。这将确保它不是偶然发生的。
附:通常避免在一个单元测试中使用多个线程
【讨论】: