unit testing实时/并发软件

可能重复:
我该如何对线程代码进行unit testing?

经典的unit testing基本上只是将x放入并期望y out,并使该过程自动化。 因此,测试任何不涉及时间的东西都是有益的。 但是,我遇到的大部分非常重要的错误都与时间有关。 线程会破坏彼此的数据,或导致死锁。 不确定性的行为发生了 – 一万分之一。 硬的东西。

对于multithreading并发系统的“unit testing”部分,有什么有用的东西吗? 这些测试如何运作? 是否有必要长时间运行此类测试的主题并以一种巧妙的方式改变环境,以确信其工作正常?

我目前做的大部分工作都涉及multithreading和/或分布式系统。 大多数错误涉及“发生在之前”类型错误,其中开发人员(错误地) 假设事件A将始终发生在事件B之前。但是,每运行一次程序,事件B首先发生,这会导致不可预测的行为。

此外,没有任何好的工具可以检测时序问题,甚至是竞争条件造成的数据损坏。 像Valgrind工具包中的Helgrind和drd这样的工具非常适合于琐碎的程序,但它们在诊断大型复杂系统时并不是很有用。 首先,他们经常报告误报(特别是Helgrind)。 另一方面,在Helgrind / drd下运行时实际检测某些错误很困难,因为在Helgrind下运行的程序运行速度慢了近1000倍,并且你经常需要运行一个程序很长时间才能重现竞争条件。 此外,由于在Helgrind下运行完全改变了程序的时序,因此可能无法再现某个时序问题。 这是微妙时间问题的问题; 他们几乎是海森堡式的,因为改变计划以检测时间问题可能会掩盖原始问题。

可悲的事实是,人类仍然没有充分准备好处理复杂的并发软件。 不幸的是,没有简单的方法对其进行unit testing。 特别是对于分布式系统,您应该使用Lamport的先前发生的图表仔细规划您的程序,以帮助您确定程序中必要的事件顺序。 但最终,你无法真正摆脱随机变化输入的暴力unit testing。 它还有助于在unit testing期间改变线程上下文切换的频率,例如运行另一个占用CPU周期的后台进程。 此外,如果您可以访问群集,则可以并行运行多个unit testing,这可以更快地检测错误并为您节省大量时间。

如果你可以在Linux下运行你的测试,valgrind包含一个名为helgrind的工具,它旨在检测使用pthreads的程序中的竞争条件和潜在的死锁; 您可能会从运行multithreading代码中获得一些好处,因为它会报告潜在错误,即使它们实际上并未在特定测试运行中发生。

我从来没有听说过任何可以做到的事情。

我想如果有人要设计一个,它必须完全控制线程的执行并执行所有可能的线程步进组合。

听起来像是一项重大任务,更不用说当有少量或更multithreading时,非平凡大小线程的数学组合……

虽然,快速搜索stackoverflow … unit testingmultithreading应用程序?

如果测试的系统足够简单,您可以通过阻止外部模型系统中的操作来很好地控制并发性。 例如,可以通过等待一些其他操作开始来完成该阻塞。 如果您可以控制所有外部调用,则可以通过实现不同的阻塞序列来很好地工作。 我已经尝试了这个,如果你很清楚可能有问题的序列,它确实可以很好地揭示锁定级错误。 与许多其他并发测试相比,它是非常确定的。 然而,这种方法不能很好地检测低水平竞争条件。 我通常只是去进行负载测试以找到那些,但我认为这不完全是unit testing。

我已经看到了.net的这些并发测试框架,我假设有人为Java编写一个(希望如此)之前的时间问题。

而不是忘记良好的旧代码阅读。 找到并发错误的最好方法之一就是再次阅读代码,让它完全集中注意力。

也许答案是你不应该。 在并发系统中,可能并不总是存在一个正确的确定性答案。

以人们登上火车并选择座位为例。 你每次都会得到不同的结果。

当您需要在测试中处理异步性时, Awaitility是一个有用的框架。 它允许您等到系统中的某个状态更新。 例如:

await().untilCall( to(myService).myMethod(), equalTo(3) ); 

要么

 await().until( fieldIn(myObject).ofType(int.class), greaterThan(1)); 

它还具有Scala和Groovy支持。