运行all时单元测试失败,但单独运行时单元测试失败

时间:2017-02-16 02:49:45

标签: c# visual-studio unit-testing

对于不同的场景我有大约12个单元测试,我需要在这些测试中调用一个异步方法(有时在一个测试中多次)。当我执行“全部运行”时,其中3个将始终失败。如果我使用“运行选定的测试”逐个运行它们,它们将通过。我得到的输出异常是:

  

System.AppDomainUnloadedException:尝试访问已卸载的   AppDomain中。如果测试开始一个线程但没有开始,则会发生这种情况   停下来。确保测试启动的所有线程都是   在完成之前停止。

我无法真正分享代码,因为它非常大而且我不知道从哪里开始,所以这里有例子:

[TestMethod]
public async Task SampleTest()
{
    var someProvider = new SomeProvider();

    var result = await someProvider.IsSomethingValid();

    Assert.IsTrue(result == SomeProvider.Status.Valid);

    NetworkController.Disable();

    result = await someProvider.IsSomethingValid();

    Assert.IsTrue(result == SomeProvider.Status.Valid);

    NetworkController.Enable();
}

编辑: 其他两种失败的方法分别为未来和过去设定时间。

[TestMethod]
public async Task SetTimeToFutureTest()
{
    var someProvider = new SomeProvider();

    var today = TimeProvider.UtcNow().Date;

    var result = await someProvider.IsSomethingValid();

    Assert.IsTrue(result == SomeProvider.Status.Valid);

    TimeProvider.SetDateTime(today.AddYears(1));

    var result2 = await someProvider.IsSomethingValid();

    Assert.IsTrue(result2 == SomeProvider.Status.Expired);
}

TimeProvider的样子如下:

public static class TimeProvider
{
    /// <summary> Normally this is a pass-through to DateTime.Now, but it can be overridden with SetDateTime( .. ) for testing or debugging.
    /// </summary>
    public static Func<DateTime> UtcNow = () => DateTime.UtcNow;

    /// <summary> Set time to return when SystemTime.UtcNow() is called.
    /// </summary>
    public static void SetDateTime(DateTime newDateTime)
    {
        UtcNow = () => newDateTime;
    }

    public static void ResetDateTime()
    {
        UtcNow = () => DateTime.UtcNow;
    }
}

编辑2:

    [TestCleanup]
    public void TestCleanup()
    {
        TimeProvider.ResetDateTime();
    }

其他方法类似,我将模拟时间/日期变化等。

我尝试通过从它获取.Result()等同步调用该方法,但它没有帮助。我在网上阅读了关于这个但仍在努力的材料。

有没有人遇到同样的问题?任何提示都将受到高度赞赏。

3 个答案:

答案 0 :(得分:1)

我无法看到您在测试初始化​​或清理时所做的事情,但可能是因为所有测试方法都试图异步运行,因此测试运行器不允许所有任务完成在进行清理之前。

运行所有测试时,相同的几种方法是否失败,还是随机的?您确定要进行单元测试而不进行集成测试吗?班级&#34; NetworkController&#34;给我的印象是你可能正在做更多的集成测试。如果是这种情况并且您使用的是公共类,提供者,服务或存储介质(数据库,文件系统),则由一种方法引起的交互或状态更改可能会影响另一种测试方法的功效。

答案 1 :(得分:0)

在异步/等待模式下运行测试时,会产生一些延迟。看起来你的所有处理都发生在内存中。他们可能一个接一个地通过,因为滞后时间很短。在异步模式下运行多个时,延迟时间足以导致时间结果的区别。

在进行由NCrunch运行的NUnit测试之前,我已经遇到了这个问题,其中正在测试DateTime组件。您可以通过将验证/到期逻辑的范围缩小到匹配秒而不是毫秒来缓解此问题,只要在您的验收标准中允许这样做。我无法从您的代码中看出逻辑是什么驱动验证状态或到期日期,但我愿意打赌,异步延迟是同时运行时测试失败的根本原因。

答案 2 :(得分:0)

显示的两个测试都使用相同的静态TimeProvider,因此在清理和TimeProvider.SetDateTime(today.AddYears(1))中使用ResetDateTime等方法干扰;在测试中是可以预期的。此外,NetworkController似乎是一个静态资源,连接/断开它可能会干扰您的测试。

您可以通过多种方式解决问题:

  • 摆脱静态资源,改为使用实例
  • 锁定测试,以便一次只能运行一个测试

除此之外,几乎每个测试框架都提供的不仅仅是Assert.IsTrue。你的框架不提供Assert.AreEqual吗?这提高了可读性。此外,在测试中使用多个Assert时,建议使用自定义消息指示哪个测试失败(或者Assert是针对前置条件而不是实际测试)。