单元测试——最佳实践



我使用Visual Studio 2010 Professional和MSTest框架来执行单元测试。我有讨厌的生产代码要测试。第一个问题是有问题的代码在构造函数中。我将展示一个例子:

class ClassToTest
    {
        public SomeEnum UpperBorder;
        public SomeEnum LowerBorder;
        public int var1;
        private readonly SomeEnum2 _ethnicGroup;
        private readonly double _age;
        public int DataStart;
        public int DataEnd;
        public double[] DarkRedDarkYellow;
        public double[] DarkYellowGreen;
        public double[] GreenLightYellow;
        public double[] LightYellowLightRed;
        public ClassToTest(SomeEnum upperBorder, SomeEnum lowerBorder, int var1, SomeEnum2 ethnicGroup, int age)
        {
            UpperBorder = upperBorder;
            LowerBorder = lowerBorder;
            BscanIndex = bscanIndex;
            _ethnicGroup = ethnicGroup;
            _age = age;
            DataStart = 0;
            DataEnd = 0;
            DarkRedDarkYellow = null;
            DarkYellowGreen = null;
            GreenLightYellow = null;
            LightYellowLightRed = null;
        }
}
我的问题是:
  • 为每个变量写一个带有断言语句的测试?或者编写几个测试,在每个测试中一次只检查一个变量?例如:

,

[TestMethod()]
public void ClassToTest_Constructor_upperBorder_PTest()
{
    //ACT
    var ob = new ClassToTest(SomeEnum.bor1, SomeEnum.bor2,10,SomeEnum2.Asian,10);
    //ASSERT
    Assert.IsNotNull(object);
    Assert.AreEqual(ob.upperBorder,SomeEnum.bor1);
}
  • 我应该检查构造函数是否正确地将参数分配给私有字段?或者,如果有属性返回私有字段,但它执行一些其他操作,如触发器事件,日志操作等。

我找不到关于它的任何信息。所以你的建议将是最宝贵的。

我将编写一个包含多个断言的测试。我知道有些人反对这样做,但我认为在一个测试中测试一个方法并验证该方法的所有相关后置条件是可以的。否则你将会有大量的测试方法。

单元测试通常不测试

私有字段。单元测试最好测试外部可见的行为和状态。

我认为一个好的规则是为单元测试争取尽可能完整的代码覆盖率。如果构造函数和对字段的赋值中存在错误,则应该在其他更高级的测试中捕获,如果它们具有适当的覆盖率。我认为为类的私有部分编写测试的唯一原因是很难触发某些场景,例如错误处理例程。在处理线程时,也可能有理由在执行测试之前获取某些私有锁,以模拟特定的调度场景。

为每个变量写一个assert语句的测试:

你正在测试构造函数是否正确地赋值给它。

如果您有多个构造函数,具有不同数量的参数,那么我建议为每个构造函数编写单独的测试。

如果构造函数也设置了私有字段,那么可以也测试这些字段——有些人不喜欢在单元测试中检查私有成员。实际上,对于设计良好的代码,这应该是不必要的。

然而

。我个人经常发现,对于没有考虑到单元测试的遗留代码,偶尔测试私有成员可能是实现良好测试覆盖率的最简单方法。

查看这篇文章,了解实现这一目标的简单方法。

对于此类问题,我找到的最佳解决方案是:

  1. 将构造代码移动到受保护的初始化方法中,该方法从构造函数调用。让你的构造函数保持相同的参数,不要创建一个默认的(没有参数的)构造函数。
  2. 对于你的测试,创建一个继承的可测试版本,它应该有以下内容:
    • 一个默认构造函数,它什么都不做(甚至不调用初始化器)
    • 受保护初始化器的公共重载
    • 要验证的任何私有/受保护值的公开属性
此时,您可以像测试任何其他方法一样测试初始化式。如果所有初始化器所做的是将值填充到成员变量中,那么一个测试,断言所有的值就足够了;但是,如果您的初始化器有任何条件逻辑,请确保编写足够的测试来执行该逻辑。

在编写单元测试时需要考虑一些要点,如下所示

  1. 独立项目进行单元测试。
  2. 一个类用于在一个主代码类中编写函数的单元测试。
  3. 涵盖功能内的条件
  4. 测试驱动开发

如果你真的想知道更多(有例子),看看这个教程

单元测试c# -最佳实践https://www.youtube.com/watch?v=grf4L3AKSrs

最新更新