我是单元测试领域的新手,这周我刚决定为我现有的应用程序增加测试覆盖率。
这是一项巨大的任务,主要是因为要测试的类的数量,但也因为编写测试对我来说是全新的。
我已经为很多类编写了测试,但是现在我想知道我做的是否正确。
当我为一个方法编写测试时,我有一种重新编写方法本身的感觉。
我的测试似乎与该方法紧密地绑定在一起(测试所有代码路径,期望使用某些参数多次调用一些内部方法),以至于如果我重构该方法,即使该方法的最终行为没有改变,测试也会失败。
这只是一种感觉,正如前面所说,我没有测试的经验。如果有更有经验的测试人员能给我一些建议,告诉我如何为现有的应用程序编写出色的测试,我将不胜感激。
编辑:我要感谢Stack Overflow,我在不到15分钟的时间里得到了很好的输入,回答了我刚才做的更多小时的在线阅读。
我的测试似乎与该方法紧密地绑定在一起(测试所有代码路径,期望使用某些参数多次调用一些内部方法),以至于如果我重构该方法,即使该方法的最终行为没有改变,测试也会失败。
我认为你做错了。
一个单元测试应该:
测试一种方法
为该方法提供一些特定的参数
测试结果是否符合预期
它不应该在方法内部查看它正在做什么,因此改变内部内容不应该导致测试失败。您不应该直接测试私有方法是否被调用。如果您有兴趣了解您的私有代码是否正在被测试,那么可以使用代码覆盖工具。但不要被这一点所困扰:100%的覆盖率并不是要求。
如果您的方法调用其他类中的公共方法,并且这些调用由您的接口保证,那么您可以使用模拟框架测试这些调用是否正在进行。
您不应该使用方法本身(或它使用的任何内部代码)来动态生成预期的结果。预期的结果应该硬编码到您的测试用例中,这样当实现改变时它就不会改变。下面是一个简单的单元测试示例:
testAdd()
{
int x = 5;
int y = -2;
int expectedResult = 3;
Calculator calculator = new Calculator();
int actualResult = calculator.Add(x, y);
Assert.AreEqual(expectedResult, actualResult);
}
注意,不检查计算结果的方式,只检查结果是否正确。继续像上面那样添加越来越多的简单测试用例,直到您已经覆盖了尽可能多的场景。使用代码覆盖工具查看是否遗漏了任何有趣的路径。