单元测试 - 最佳实践

时间:2011-07-21 09:22:47

标签: c# visual-studio-2010 unit-testing mstest

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

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;
        }
}

我的问题是:

  • 为每个变量用assert语句编写一个测试?或写几个测试,并在每个测试中一次只检查一个变量?例如:

[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);
}
  • 我应该检查构造函数是否正确地将参数分配给私有字段?或者,如果有属性返回该私有字段,但它执行另一个操作,如触发器事件,日志操作等。

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

4 个答案:

答案 0 :(得分:6)

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

私人字段通常不会通过单元测试进行测试。单元测试应该优先测试外部可见的行为和状态。

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

答案 1 :(得分:4)

使用assert语句为每个变量编写一个测试获得我的投票:

您正在测试构造函数是否正确分配了给它的值。

如果你有多个构造函数,参数数量不同,那么我主张为每个构造函数编写一个单独的测试。

如果构造函数也设置了私有字段,那么可以也测试这些 - 有些人不喜欢在单元测试中检查私有成员。实际上,通过精心设计的代码,这不是必需的。

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

查看this文章,了解实现此目标的简便方法。

答案 2 :(得分:0)

我发现这些问题的最佳解决方案是:

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

答案 3 :(得分:0)

在编写单元测试时需要考虑一些要点

  1. 单独测试项目。
  2. 一类用于在一类主代码中编写函数的单元测试。
  3. 涵盖职能范围内的条件
  4. 测试驱动开发(TDD)
  5. 如果您真的想了解更多(使用示例),请查看本教程

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