C# 如何测试阻塞功能?
如何在特定情况下测试函数是否无限期阻塞C# 如何测试阻塞功能?,c#,nunit,C#,Nunit,如何在特定情况下测试函数是否无限期阻塞 [Test] public void BlockingTest() { blockingFunction(); // this function halts execution indefinitely Assert.Fail("Execution not halted."); } 假设blockingFunction()是一个等待事件发生的函数,它应该阻止执行,直到某个特定事件发生,并且测试假设该事件永远不会发生 编辑:我实际上
[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");
}
[测试]
公共无效块测试(){
BytesStream bs=新的BytesStream();
写入(新字节[]{1,2},0,2);
var buff2=新字节[2];
读(2,0,2);
bool datawrited=false;
新线程(()=>{
对于(int i=0;i,可以让函数由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);
}
可能让您的函数由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);
}
您已经回答了您的问题。如果blockingFunction
更早返回,您的测试方法将无限期等待并失败。只要让它运行并修复失败的代码即可
现在回答真正的问题:你真正想测试什么
blockingFunction
阻塞执行实际上是一种要求吗?我认为如果它能够在不阻塞执行的情况下使用队列项,那就更好了——但是你虚构的测试会失败
换句话说:我假设你的blockingFunction
阻塞并不重要,你应该测试业务逻辑而不是技术行为,除非有实际的用例
例如,如果消费者在t
秒内没有生成任何项目就终止,那么您可以等待t
秒,如果它返回得更早,则会失败
如果您想测试消费者在闲置一段时间后是否“醒来”,您可以等待n
秒,然后生成一个项目。失败消费者会在之前做一些事情,如果在生成项目后没有消费,则失败
只有你才能真正回答这个问题,因为我们不知道你实际上想在这里测试什么。我希望我能以一种有帮助的方式解释清楚。你已经回答了你的问题。你的测试方法将无限期地等待,如果阻塞函数
返回得更快,你的测试方法就会失败。只要如果出现故障,请不要运行并修复代码
现在回答真正的问题:你真正想测试什么
blockingFunction
阻塞执行实际上是一种要求吗?我认为如果它能够在不阻塞执行的情况下使用队列项,那就更好了——但是你虚构的测试会失败
换句话说:我假设你的blockingFunction
阻塞并不重要,你应该测试业务逻辑而不是技术行为,除非有实际的用例
例如,如果消费者在t
秒内没有生成任何项目就终止,那么您可以等待t
秒,如果它返回得更早,则会失败
如果您想测试消费者在闲置一段时间后是否“醒来”,您可以等待n
秒,然后生成一个项目。失败消费者会在之前做一些事情,如果在生成项目后没有消费,则失败
只有你才能真正回答这个问题,因为我们不知道你到底想在这里测试什么。我希望我能以一种有帮助的方式解释清楚
如何在特定情况下测试函数是否无限期阻塞
[Test]
public void BlockingTest()
{
blockingFunction(); // this function halts execution indefinitely
Assert.Fail("Execution not halted.");
}
这就是所谓的问题。这是不可能解决的
如何在特定情况下测试函数是否无限期阻塞
[Test]
public void BlockingTest()
{
blockingFunction(); // this function halts execution indefinitely
Assert.Fail("Execution not halted.");
}
这就是所谓的。可以证明这是不可能解决的。只要等待无限长的时间,你就会证明它永远不会返回。我认为你做不到这一点,但如果你能解释更多关于代码的内容,可能还有另一种方法。简化:我有一个队列,生产者向队列写入一些数据,消费者读取它。如果有如果没有生产者,消费者将不得不无限期地等待。我已通过生成生产者线程并等待几秒钟来修补测试,然后才真正将某些内容发送到队列取消阻止消费者,我正在寻找一个更优雅的解决方案。感谢您等待无限长的时间,那么您将证明它永远不会返回。我是这样做的我不认为你能做到这一点,但如果你能对代码做更多的解释,可能还有另一种方法。简化:我有一个队列,生产者向队列中写入一些数据,消费者读取。如果没有生产者,消费者将不得不无限期地等待。我通过生成生产者线程并在测试前等待几秒钟来修补测试实际上,我正在向队列发送一些东西以解除对消费者的阻止,我正在寻找一个更优雅的解决方案。谢谢这与我现在正在做的非常相似,我正在寻找一些更优雅的东西。可能不会阻止测试执行超过几毫秒。如果您指定ev.WaitOne(50,…)
然后测试函数是否在50毫秒内返回。我在BlockingFunction()中进行了快速测试(使用500或5000毫秒的睡眠时间)
在我的答案中包含代码,它似乎正确地测试了它。但我不知道如何使它更优雅。抱歉。谢谢你的回答。这几乎是不可能发生的,但由于某种原因,假设子线程执行时间超过50毫秒,测试会错误地失败。你不应该断言ev.WaitOne吗
返回false
?如果ev.WaitOne
返回true,则b