【发布时间】:2021-05-27 16:12:30
【问题描述】:
目标
我想测试一些接受 IProgress 的异步调用的进度报告。 我要验证:
- 如果此报告的进度始终在 [0.0; 1.0]
- 具有递增的值(上一个值
- 在某些时候报告 1.0,例如作为最后一次调用
我想使用尽可能少的框架 -> 不使用另一个 3. 方库的解决方案会很好。
问题/我的尝试
我尝试编写一个简单的异步任务测试方法来实现这一点。我调用方法来测试等待,例如。 await asyncCallToTest(new Progress((p) => { Assert.someting(p); }))。并且可能在 lambda 中使用堆栈变量。后面有完整的例子。
然而,这导致测试成功,即使它不应该是可能的,或者有时测试通过了,然后它没有改变就失败了......
代码
我用一个简单的独立测试类重新创建了问题:
using System;
using System.Threading.Tasks;
using NUnit.Framework;
namespace FastProgressReporter
{
public class Tests
{
[Test]
public async Task SampleOkTest()
{
await TestReporter(new Progress<double>((p) => {
Assert.GreaterOrEqual(p, 0);
Assert.LessOrEqual(p, 1);
}));
//Sometimes fails, sometims passes. Why?
}
[Test]
public async Task SampleFailTest()
{
await TestReporter(new Progress<double>((p) => {
Assert.GreaterOrEqual(p, 2); // Has to Fail, however passes.
Assert.LessOrEqual(p, 3);
}));
}
[Test]
public async Task ReportsIncremental()
{
double latestProgress = 0;
await TestReporter(new Progress<double>((p) => {
p = 1 - p; //Force Decrement...
Assert.GreaterOrEqual(latestProgress, p); //Should fail on second call
latestProgress = p;
}));
}
[Test]
public async Task ReportsOneOneOrMoreTimes()
{
double maxProgress = 0;
await TestReporter(new Progress<double>((p) => {
maxProgress = p > maxProgress ? p : maxProgress;
}));
Assert.AreEqual(0, maxProgress); //Should always fail
//Sometimes fails, sometims passes. Why?
}
// Methode under test
public static async Task TestReporter(IProgress<double> progress)
{
progress.Report(0);
await Task.Run(() => { /*Do nothing, however await*/ });
progress.Report(0.5);
await Task.Run(() => { /*Do nothing, however await*/ });
progress.Report(1);
}
}
}
环境
VisualStudio 2019,.net-framework 4.7.2,NUnit3 测试项目
问题
我如何可靠且正确地实现我的目标?
相关问题
Verifying progress reported from an async call is properly report in unit tests 这使用了一个我试图避免的 3 方库,并且在测试方法中直接调用 .Report(),而不是在测试调用的异步方法中
感谢您的帮助。
【问题讨论】:
-
ty,固定@Fildor
-
我会试试这个:让
Progress将所有值附加到列表中。然后在清单上做出你的断言。 (应该“排序”,不应该为空,应该有 X 项,第一项应该是 A,最后一项应该是 B ...) -
我会使用
await Task.Delay(someMillis);而不是await Task.Run( () => { /* Nothing really */ }); -
使用 Task.Delay 或 Task.Yield 而不是 Task.Run。变化不大,但这些方法更适合您希望通过 Task.Run 实现的目标。
标签: c# unit-testing asynchronous .net-4.0 nunit-3.0