如何在特定情况下测试函数是否无限期阻塞?
[Test]
public void BlockingTest()
{
blockingFunction(); // this function halts execution indefinitely
Assert.Fail("Execution not halted.");
}
假设blockingFunction()
是一个等待某事发生的函数,它应阻止执行直到发生特定事件,并且测试假设此事件永远不会发生。
编辑:我真正想要的是一个优雅的解决方案,可能无需在报告成功之前明确等待硬编码时间。
发布我目前的情况以供参考:
[Test]
public void BlockTest() {
BytesStream bs = new BytesStream();
bs.Write(new byte[] { 1, 2 }, 0, 2);
var buff2 = new byte[2];
bs.Read(buff2, 0, 2);
bool dataWritten = false;
new Thread(() => {
for(int i=0; i<100; i++)
Thread.Sleep(0); // ensure the parent thread execute next line
dataWritten = true;
bs.Write(new byte[] { 3, 4 }, 0, 2);
}).Start();
Assert.AreNotEqual(0, bs.Read(buff2, 0, 2), "#1");
if(!dataWritten)
Assert.Fail("#2");
Assert.AreEqual(new byte[] { 3, 4 }, buff2, "#3");
}
答案 0 :(得分:3)
如何在特定情况下测试函数是否无限期阻塞?
这称为Halting Problem。可以证明无法解决。
答案 1 :(得分:1)
也许让你的函数由Threadpool对象执行,看看它是否在指定的时间范围内返回,如下所示:
[Test]
public void BlockingTest()
{
AutoResetEvent ev = new AutoResetEvent(false);
BlockingFunctionHelper(ev);
// specify time out in ms, thus here: wait 1 s
Assert.IsTrue(ev.WaitOne(1000), "Execution not halted.");
ev.Dispose();
}
private void BlockingFunctionHelper(AutoResetEvent ev)
{
ThreadPool.QueueUserWorkItem((e) =>
{
BlockingFunction(); // this function halts execution indefinitely
((AutoResetEvent) e).Set();
}, ev);
}
答案 2 :(得分:0)
您已经回答了您的问题。如果blockingFunction
更快返回,您的测试方法将无限期等待并失败。如果代码失败,只需让它运行并修复代码。
现在回答这里的真正问题:你真正想要测试什么?
实际上要求blockingFunction
阻止执行吗?我假设如果它在没有阻止执行的情况下使用队列项,它会更好 - 但是你的虚构测试会失败。
换句话说:我认为你的blockingFunction
阻止并不重要,你应该测试业务逻辑而不是技术行为,除非有一个实际的用例。
如果您的消费者在t
秒内没有生成任何项目时终止,那么您可以等待t
秒,如果它更早返回则会失败。
如果你想测试你的消费者是否醒来&#34;闲置一段时间后,您可以等待n
秒,然后生成一个项目。失败的消费者会提前做某事,如果生成你的商品后没有消费就会失败。
只有你能真正回答这个问题,因为我们不知道你实际想要在这里测试什么。我希望我能以一种有益的方式拼出来。