65.9K
CodeProject 正在变化。 阅读更多。
Home

查找构建和测试运行中缺少的单元测试

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2016年10月3日

CPOL

3分钟阅读

viewsIcon

11644

查找测试结果中未显示的单元测试。

引言

很多时候,我们运行了数千次测试,却发现**只有几百次真正完成**,或者**数百次测试缺失**。问题来自**破坏测试执行系统**的测试。大多数情况下,我们无法在开发环境中重现这个问题,但在构建环境中,测试会持续破坏测试运行程序。

背景

我们发现,在**XAML构建**和**VNext构建**中使用**_mstest_**或_**vstest.console.exe**_时会出现此问题。下面,我将测试称为“breaking”,这意味着测试导致异常,从而破坏了测试执行程序,这与测试失败不同。有时,必须在构建服务器上以正确的设置运行失败的测试才能重现问题。

查找问题

首先需要做的就是**找到导致问题的测试**。

测试可能由于许多地方的问题而“breaking”,包括TestInitializeClassInitialize等。因此,我们需要某种方法来跟踪哪个测试有问题以及它在哪里有问题。

  1. 在我看来,**最快捷的方法是让测试记录到一个滚动尾部日志文件**,该文件在测试的不同部分更新。大多数情况下,我们在ClassIntializeTestInitializeTestMethod本身中看到问题。Log4Net可以有效地创建这些日志。这应该能够**显示破坏系统的测试**以及它在哪里中断。我们跟踪以下内容的开始和结束
    • AssemblyInitialize
    • ClassInitailize
    • TestInitialize
    • TestCleanup
    • ClassCleanup
    • AssemblyCleanup
  2. 您还可以查看测试运行的_.trx_文件,以查看**最后运行的测试**,它将是最后一个UnitTestResult元素。这只会显示最后成功运行的测试,但是您必须弄清楚**下一个测试是什么**。

如果您选择了**方案1**,您可以查看日志,应该能够找到导致执行程序中断的问题测试。如果它在ClassInitialize中失败,您应该会看到Class Initialize Started,但不会看到Class Initialize Finished。

如果您选择**方案2**,则需要更进一步才能获得**测试按运行顺序排列的列表**。由于您应该**知道在破坏系统测试之前运行的最后一个测试**,您可以简单地找出**下一个测试应该是哪个**。使用Reflection,您可以获取测试程序集中具有TestMethod属性的方法。下面是我们运行的UnitTest,用于获取按运行顺序排列的测试列表。

    [TestClass]
    public class Utilities
    {
        [TestMethod]
        [TestCategory("Utility")]
        public void GetTestMethods()
        {
            foreach (var type in System.Reflection.Assembly.GetExecutingAssembly().GetTypes())
            {
                foreach (var method in type.GetMethods())
                {
                    foreach (var attrib in method.CustomAttributes.Select(c => c.ToString()))
                    {
                        if (attrib.ToString().Contains("TestMethodAttribute"))
                        {
                            Console.WriteLine(method.Name);

                            break;
                        }
                    }
                }
            }
        }
    }

运行测试后,可以通过打开**测试资源管理器**,然后单击GetTestMethods并单击**输出**来查看结果。这将显示**按运行顺序排列的测试列表**,只需找到_.trx_文件中列出的最后一个测试,然后找出下一个测试。

关于修复测试的一句话

我不想深入探讨如何修复您的测试,但我认为我会添加我们遇到的**最常见的场景**。

  1. **断言对象为空**。如果对象不为null,但对象的属性为null,则测试会失败但可以,但是如果您尝试访问null对象的属性,则会中断。
  2. 我们的大多数问题都来自**异步调用中的竞争条件**,这可能是异步方法在测试完成后返回,或者在异步结果上使用某些Assert方法,其中评估发生在返回结果之前。
© . All rights reserved.