【问题标题】:Xunit Timeout parameter: minimal working exampleXunit Timeout 参数:最小的工作示例
【发布时间】:2018-08-04 23:15:04
【问题描述】:

我正在尝试创建一个最小的工作示例,说明 Xunit.net 中的 Timeout 参数如何运行。我目前有以下Fact 示例,但它没有按我的预期运行,因为它没有通过测试:

[Fact(Timeout = 50)]
public void FactTimeout_TimeoutLessThanProcessingTime_ThrowTestTimeoutException()
{
    // Arrange
    // Act
    Action act = () => Task.Delay(5000);

    // Assert
    Assert.Throws<TestTimeoutException>(act);
}

这是正确的,还是我的理解错误?是否还有其他需要更改或添加到测试本身或 Xunit 配置的内容?

更新

根据@RubenBartelink 的回答,我得到了以下工作:

// Will generate the exception and display it in the results window
[Fact(Timeout = 50)]
public async void TestOne() => await Task.Delay(5000);

// This will pass the test, but will complain that it is not awaited
[Fact(Timeout = 50)]
public void TestTwo() => Assert.ThrowsAsync<TestTimeoutException>(() => Task.Delay(5000));

【问题讨论】:

  • 你需要await ThrowsAsync - 否则你刚刚产生了一个Task,没有人会检查它的结果。但问题是 TestTimeoutException 是一个内部异常,在测试超时时由 xUnit 抛出 - 没有其他真正的方法可以让它在你的测试主体中抛出(对我来说,这是你的问题)正在寻求实现整体 - 如果在您的实际代码中超时,您会怎么做?)
  • @RubenBartelink 啊,我应该在前面更清楚。我正在创建一个示例项目来演示如何使用 Xunit 的不同方面。因此,您认为这种方法不适合实际测试是正确的。 Timeout 参数可以在异步情况下使用吗,比如说你有一段同步的代码需要很长时间?
  • 是的,无论同步还是异步,超时都适用。一般来说,对于一个整体的测试套件,我会考虑为整个测试套件设置一个超时时间(通常任何跑步者都会有这样的设施,就像 xunit.runner.console 用于 instacne 一样)然后让 CI 钻机的时间引导您处理通常花费太长时间的任何事情。也就是说,虽然 Timeout 工具在需要时可能是不可或缺的,但我倾向于在任何高级概述中都不会提及它
  • 所以事实证明 Timeout 参数当前不适用于同步代码,我最终在 xunit.slack 频道上询问,因为我无法获得同步示例。跨度>
  • 啊,有趣。 :thinking: 有没有什么办法可以通过async Task Test () =&gt; {.... (take &gt;50ms); await Task.FromResult(0); } 滥用它 - 让我们假装这个想法没有进入我的脑海!

标签: c# timeout xunit.net


【解决方案1】:

您可能的意思是使用 Assert.ThrowsAsync - 否则您正在测量启动任务需要多长时间(假设 50 表示您打算设置 50 毫秒的超时时间,而您只是想要证明它确实会失败)

虽然在某些情况下您可以避免它,但总的来说,我将这种异步测试方法设为 async Task ... 并确保其中有一个 await 以便更容易遵循流程(假设 Async ness 是测试的关键)

您可能会在https://github.com/xunit/xunit/issues/217 中找到有用的讨论/示例


编辑:根据您的评论示例未经测试的 impl

我正在尝试创建一个最小的工作示例,说明 Xunit.net 中的 Timeout 参数如何运行。我目前有以下 Fact 示例,但它没有按我的预期运行,因为它未通过测试:

[Fact(Timeout = 50)]
public async Task FactTimeout_TimeoutLessThanProcessingTime_ThrowTestTimeoutException()
{
    Action act = () => Task.Delay(5000);

    // Trigger the timeout by attempting something that will take too long
    await act;
}

这应该在内部导致测试超时(您试图捕捉的TestTimeoutException)。我怀疑你不会有一个巧妙的方法来捕捉有问题的异常 - 如果你需要观察超时发生并做出反应并做一些明确的事情(你最好避免在测试中这样做),你会需要通过大致这样的Task.WhenAny 来明确管理它:

public async Task FactTimeout_TimeoutLessThanProcessingTime_ThrowTestTimeoutException()
{
    Action act = () => Task.Delay(5000);

    let timeoutTask = Task.Delay(50);
    let res = await Task.WhenAny(timeoutTask, act);

    Assert.IsSame(timeoutTask, res);
}

注意,这只是一个示例,表明超时确实发生并且可以观察到 - 前一种方法具有正确的 awaiting 并让 xUnit 管理超时而不用这种逻辑污染测试是你想要的到达。

【讨论】:

  • 您能否提供一个测试抛出TestTimeoutException 的最小示例?以前我尝试过Thread.Sleep,但结果相同。
  • 没有准备好环境,但会添加一个可以尝试的内联示例
  • 我已根据您的回答为我的问题添加了更新。我找到了通过该测试的方法,但找不到这样做的方法并摆脱不等待呼叫的消息。你能想到什么改变来实现这两者?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-08
  • 2015-06-19
  • 1970-01-01
  • 2019-05-23
  • 2018-08-28
  • 2017-06-18
相关资源
最近更新 更多