使用nUnit测试死锁

时间:2009-01-23 12:25:02

标签: c# unit-testing nunit deadlock

我是单元测试和nUnit(2.48)的新手。我想写一个测试方法,其中失败的情况是它死锁。这可能吗?显然,nUnit默认情况下不知道该方法应该执行多长时间,因此我是否必须编写代码来在单独的线程上完成工作然后中止它并抛出异常(如果花费的时间超过我定义的时间)?有更好的方法吗?

谢谢

5 个答案:

答案 0 :(得分:7)

通过在另一个线程上运行代码并查看它是否及时返回,它当然可以测试死锁。这是一些(非常基本的)示例代码:

[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);
    }
}

我不想说这是“最好的方式”,但我发现它是有用的。

答案 1 :(得分:5)

这是可能的,但它可能不是最好的事情。单元测试并不适合测试并发行为,遗憾的是没有多少适合的测试方法。

NUnit不会对线程做任何事情。您可以编写启动多个线程的测试,然后测试它们的交互。但是这些开始看起来更像集成测试而不是单元测试。

另一个问题是死锁行为通常取决于调度线程的顺序。所以很难编写一个结论性测试来测试某个死锁问题,因为你没有对线程调度的任何控制,这是由操作系统完成。您最终可能会遇到有时在多核处理器上失败的测试,但总是在单核处理器上取得成功。

答案 2 :(得分:5)

死锁检测等同于halting problem,因此在一般情况下目前无法解决。

如果您有特定的问题要防范,可能会有特定的黑客攻击至少获得一点安全性。但请注意,这只能是一个黑客而且绝不是100%。例如,这样的测试可能总是在开发机器上传递,但从不在生产机器上传递。

答案 3 :(得分:4)

看看名为“Chess”的Microsoft Project。 它旨在找到同意的错误http://research.microsoft.com/en-us/projects/chess/

答案 4 :(得分:3)

要测试死锁,您必须在单元测试中实现状态图并检查当前状态图中的周期。状态图由作为节点的资源和作为边的依赖关系组成。 我不知道这样的事情的实现,但这就是理论。

单元测试测试数据输入和输出的正确性(主要用于后面的点),而不是测试应用程序执行流程的正确性。

Mark Heath的想法似乎合情合理,但在学术上是错误的。