我刚开始接触单元测试和nUnit(2.48)。我想编写一个测试方法,其中失败的情况是死锁。这有可能吗?显然,nUnit默认不知道该方法执行需要多长时间,所以我是否需要编写代码在单独的线程上执行工作,然后在超过我定义的某个时间后中止它并抛出异常?还有更好的方法吗?
谢谢
谢谢
当然,通过在另一个线程上运行代码并查看是否及时返回,可以测试死锁。这是一些(非常基本的)示例代码:
[TestFixture]
public class DeadlockTests
{
[Test]
public void TestForDeadlock()
{
Thread thread = new Thread(ThreadFunction);
thread.Start();
if (!thread.Join(5000))
{
Assert.Fail("Deadlock detected");
}
}
private void ThreadFunction()
{
// do something that causes a deadlock here
Thread.Sleep(10000);
}
}
我不想说这是“最好的方法”,但在某些情况下,我发现它很有用。
虽然可能可行,但这并不是最好的做法。单元测试不太适合测试并发行为,不幸的是,没有太多适合的测试方法。
NUnit对线程没有任何限制。您可以编写测试来启动多个线程,然后测试它们的交互。但这些测试看起来更像是集成测试而不是单元测试。
另一个问题是死锁行为通常取决于线程调度的顺序。因此很难编写一个确定性的测试来测试某个死锁问题,因为您无法控制线程调度,这由操作系统完成。您可能会得到在多核处理器上有时失败但在单核处理器上始终成功的测试结果。
死锁检测等同于停机问题,因此在一般情况下无法解决。
如果您有特定的问题需要防范,可能会有特定的技巧来获得至少一定程度的安全性。请注意,这只能是一个技巧,永远不可能达到100%的安全性。例如,这样的测试可能在开发机器上始终通过,但在生产机器上却始终失败。