【问题标题】:NUnit Test DebuggingNUnit 测试调试
【发布时间】:2015-07-28 17:30:34
【问题描述】:

我正在开发一个几何库。有 200 多个单元测试。

当我选择“全部运行”时,有一个特别顽固的测试会失败,但是当我单独运行该测试或在其上使用调试器时测试通过了。我确实相信当我从 Visual Studio '13 转换到 '15 版本时,问题就出现了。

现在关于几何库的一些注意事项:

对象是不可变的。

测试之间没有共享对象。

所以我的问题:这种奇怪行为的可能原因是什么?

编辑:

[Test()]
public void Plane_IntersectionWithPlane_IdenticalPlane()
{
     Plane testPlane = new Plane(new Direction(Point.MakePointWithInches(2, -1, 1)), 
                                               Point.MakePointWithInches(2, 1, 2));
     Line found = (testPlane.Intersection(testPlane));

     Line expected = new Line(new Direction(Point.MakePointWithInches(0, -1, -1)), 
                                            Point.MakePointWithInches(2, 1, 2));
     Assert.IsTrue(found.Equals(expected));
}

【问题讨论】:

  • 你有什么问题?
  • 在使用 NUnit 时是否有任何众所周知的怪癖,这些怪癖在作为组的一部分运行时可能会导致测试失败,而不是单独运行?
  • 不,这很可能在您这边。展示一个简短的、可重现的示例来演示问题,我们可以查看确切的问题。可能存在共享资源、不正确的异步性或无数其他可能性。
  • 您正在使用 Point 类静态调用函数 MakePointWithInches。一个测试可以依赖于另一个也使用此功能的测试的唯一情况是......你检查它吗?能分享一下Point类的实现吗?
  • 恕我直言,您需要提供更多详细信息。有了给定的信息,就有太多的可能性:线程、静态成员、缓存……

标签: c# unit-testing nunit


【解决方案1】:

我过去也遇到过类似的问题,但结果总是发现是底层代码元素之间的一些意外交互,或者测试的编写方式。需要检查的一些问题是:

  • 静态对象构造/销毁
  • 同步问题
  • 模拟设置/清理问题

我发现追查问题的最佳方法是采用类似于@Matthew Strawbridge 在 cmets 中建议的方法。我将 Ignore 属性添加到 Tests/TestFixtures 以删除测试,直到 run-all 开始工作,然后开始重新添加它们,直到它再次中断以缩小问题范围。

有时您还会发现忽略当前失败的测试会导致另一个测试失败。这很好地表明问题实际上是由您的另一个测试本身没有正确清理引起的。

查看失败/似乎导致失败的测试之间的代码可以帮助您缩小交互范围。测试的错误/失败原因当然也有帮助...

选择“全部运行”以可预测的顺序运行所有测试,因此测试通常每次都以相同的方式运行。如果您选择了一批测试,那么运行者可能会根据您的选择顺序选择以不同的顺序运行它们,这可能是您在选择测试时遇到不同行为的原因,而不是使用 run-all。

【讨论】:

    【解决方案2】:

    尝试以下方法:

    打开 Nunit GUI 并在运行测试之前更改设置中的上述内容:

    它曾经帮助我发现了我的问题。

    顺便说一句: 您使用的是哪个版本的 NUNIT? 如果您不知道什么是 Nunit GUI,那么您可能没有单独下载 Nunit。您可以从这里获得安装:

    http://www.nunit.org/index.php?p=download

    【讨论】:

      【解决方案3】:

      从我在测试用例中看到的情况来看,发散行为很奇怪,但测试失败是一个完全有效的结果:

      与自身相交的平面就是平面,所以如果结果被限制为一条线,那么平面上有 2 个不同点的任何线都是有效的结果,但是测试 对于一个特定的行看起来像是将执行结果逆向工程到测试预期。

      如果要求/规范非常具体地说明从身份交叉点生成的线的方向,那就另当别论了,所以也许您想在这方面提供更多的见解。

      很抱歉将此作为答案而不是评论发布 - 缺少代表。

      【讨论】:

      • 这只是一个例子,其他测试也有这种奇怪的行为。在平面与自身相交的情况下,它只会在该平面中选择一条特定的线。这是否是处理退化的好方法还有待商榷,但测试的路线是该方法应该选择的路线。 (并且是它在测试自己运行时选择的那个)
      【解决方案4】:

      请检查是否涉及任何静态变量。静态变量存在于 AppDomain 级别,因此一个测试用例设置的静态变量可能会对其他测试用例产生副作用。

      您可以先在单独的应用程序域中运行此测试用例以确认行为,然后再开始搜索静态变量。很抱歉,我从未尝试在 nunit 中创建新的 appdomain。但是这里的一个答案确实暗示了如何为测试用例创建一个新的 appdomain - Run unit tests in different appdomain with NUnit

      【讨论】:

        【解决方案5】:

        如果此测试单独通过但在与其他测试一起运行时失败,则极有可能您的类中有一些共享状态。

        如果你说我们所有的对象都是不可变的,那么我的第一个猜测是看看实现

        Line Intersection (Plane plane);
        

        您希望此方法返回一条与您的“预期”线相同的 Line,因此 Intersection 可能会根据某些共享状态返回一条线。

        你能告诉我们Intersection的实现吗?

        【讨论】:

          猜你喜欢
          • 2012-04-01
          • 2012-03-07
          • 2012-11-19
          • 1970-01-01
          • 2011-10-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多