英文:
Assert an infinite loop not to finish within seconds
问题
作为一名软件测试工程师,我正在请求我的软件开发工程师为我编写一个无限循环。
让我的同事编写的函数名为`canHalt(p)`。我已经找到一个特殊状态`p`,可以使他的`canHalt()`永远运行。所以是时候来测试它了。
我们使用C#(.net core 3.1)与xunit。
到目前为止,我有以下代码:
[Fact]
public async void RunInfiniteLoop()
{
Turing p = ...
// 这个配置将求解器置于无限循环中。
// 在3秒内,它将无法完成。
var task = Task.Run(() => Solver.canHalt(p));
var completedTask = await Task.WhenAny(task, Task.Delay(3000));
Assert.NotSame(task, completedTask);
}
目前一切顺利,但虚拟的软件开发工程师在他的`canHalt`函数中使用了`Console.Write`,导致输出充斥着我的屏幕。然后我用以下代码进行了包装:
var back = Console.Out;
Console.SetOut(System.IO.TextWriter.Null)
...
Console.SetOut(back);
这只对这个方法有效。但当我运行`dotnet test --verbosity normal`,它会运行解决方案中的所有测试,我的屏幕再次被淹没。
我猜想这是因为`Console.SetOut(back)`。在`RunInfiniteLoop()`执行完之后,`canHalt()`进程没有被终止,因此它可以继续写入标准输出。
我从 https://stackoverflow.com/q/50291467/746461 学到任务是协作的,或者我们可以传递一个`CancellationToken`,但是我们的规范规定`canHalt`只接受一个状态`p`;我不能插入一个用于测试的`CancellationToken`。
我想最好在我的测试结束时终止这个无限函数。
我应该如何做呢?
英文:
As a software test engineer, I'm asking my software development engineer to write an infinite loop for me.
Let's the function my fellow will write is canHalt(p)
. I've figured up a special state p
that can make his canHalt()
run forever. So it's high time to test it.
We use C# (.net core 3.1) with xunit.
What I have so far is
[Fact]
public async void RunInfiniteLoop()
{
Turing p = ...
// This configuration throws the solver into infinite loop.
// Within 3 seconds, it will not finish.
var task = Task.Run(() => Solver.canHalt(p));
var completedTask = await Task.WhenAny(task, Task.Delay(3000));
Assert.NotSame(task, completedTask);
}
So far so good, but the dummy SDE uses Console.Write within his canHalt function, and the output thus floods my screen. I then wrap the whole thing with
var back = Console.Out;
Console.SetOut(System.IO.TextWriter.Null)
...
Console.SetOut(back);
It does the trick for this method only. But when I run dotnet test --verbosity normal
, which runs all tests in the solution, my screen is flooded again.
I gather it is because of Console.SetOut(back)
. After RunInfiniteLoop() finishes execution, the canHalt() process isn't aborted, so it can continue writing to std.
I learned from https://stackoverflow.com/q/50291467/746461 Task is cooperative or we pass in a CancellationToken, but our specs says canHalt only accepts a state p; I can't squeeze in a token for testing purpose.
I guess it's better to abort the infinite function as the end of my test.
How would I do that?
答案1
得分: 2
不建议编写无法控制寿命的软件组件。因此,请告诉您的同事,该方法应接受并连接一个CancellationToken实例或其他一些可以在需要时终止无限循环的方式,并在测试方法之前返回某种状态,以验证该方法是否已终止。自定义的IAsyncResult派生类实例或Task实例可用于此目的。
英文:
It is not a good practice to write software components that lifespan can not be controlled. So specify to your fellow engineer that the method should accept and wire in a CancellationToken instance or some other means of ending the infinite loop on demand, and return some kind of state for vertifying that the method has terminated before the test method does. A custom IAsyncResult - derived class instance or a Task instance would serve such a purpose.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论