Unit testing 单元测试中逐步断言的值
在编写单元测试时,有时可以为可能失败的每个条件创建一个断言,或者创建一个可以捕获所有这些条件的断言。C#示例:Unit testing 单元测试中逐步断言的值,unit-testing,Unit Testing,在编写单元测试时,有时可以为可能失败的每个条件创建一个断言,或者创建一个可以捕获所有这些条件的断言。C#示例: Dictionary dict=LoadDictionary(); //可选主张: IsNotNull(dict,“LoadDictionary()返回null”); Assert.IsTrue(dict.Count>0,“字典为空”); Assert.IsTrue(dict.ContainsKey(“ExpectedKey”),“'ExpectedKey'不在字典中”); //实际对
Dictionary dict=LoadDictionary();
//可选主张:
IsNotNull(dict,“LoadDictionary()返回null”);
Assert.IsTrue(dict.Count>0,“字典为空”);
Assert.IsTrue(dict.ContainsKey(“ExpectedKey”),“'ExpectedKey'不在字典中”);
//实际对测试感兴趣的条件:
Assert.IsTrue(dict[“ExpectedKey”]=“ExpectedValue”,“'ExpectedKey'存在,但值不是'ExpectedValue'”;
在这种情况下,大型多人项目添加“可选资产”是否有价值?有更多的工作要做(如果你有很多单元测试的话),但是问题出在哪里会更清楚
我正在使用VS 2010和集成测试工具,但希望问题是通用的。建议每个测试只使用一个断言,这样,您就可以清楚地知道您正在测试什么
- 在TDD中,这将使您更容易准确地隔离测试失败后要实现的内容
- 测试工具生成的报告将更加准确
- 测试是否
LoadDictionary()代码>返回null
- 测试是否
LoadDictionary()代码>返回一个空字典
- 等等
没有一个测试包含所有这些断言。当然,没有几个测试包含这些断言的大部分,然后是每个测试要检查的实际内容。我个人认为,预先重新访问现有测试以插入可选断言没有多大价值 如果这是一个现有的项目,希望您的所有测试都能通过。如果是这样的话,它们只有在您重构和/或更改或向代码中添加某些内容时才会开始崩溃 我认为,如果测试失败,并且当测试失败时,处理这些测试会更容易。当然,您的测试会遇到一般性的失败,但是通过设置断点(或者通常只是调查),您将很容易发现失败的真正原因 或者,当测试失败时,您可以添加可选断言以澄清错误。这样,您就不会提前使用时间向不会失败的测试添加额外的断言,但这样做仍然会带来好处
但是,如果这是一个主动的步骤(正如您所建议的),概述了测试的指导原则,那么我认为这实际上取决于测试本身以及您从附加断言中获得的好处。如果知道
dict
为空,而不仅仅是缺少一个键,您将真正节省多少时间?最终,您应该只测试一件事情,因此如果您开始在一个测试中发现很多断言,那么可能是出了问题
就我个人而言,我认为一项规定所需断言的全球政策不值得实施。我认为应该根据具体情况来决定。对于一些测试,如您给出的示例,在一些附加断言中可能有很多价值。对于不太可能失败的更简单的事情,可能没有
迫使开发人员捕捉并描述每一个可能的离散故障有点消极。就像你期望它经常出现故障一样,节省几分钟的诊断时间是值得的。重要的是,当指示条变红时,能够快速了解故障的根源 假设只有一个断言:
Assert.IsTrue(dict["ExpectedKey"] == "ExpectedValue",
"'ExpectedKey' is present but value is not 'ExpectedValue'");
当LoadDictionary()返回null时会发生什么?如果这会使整个单元测试应用程序崩溃,就像在C/C++中发生的那样,那么就需要一个断言保护。如果失败消息清楚地表明dict为null,那么可选断言是没有意义的
第二个问题是当预期的键没有出现在字典中时会发生什么?同样,错误消息应该做出区分。如果测试与键关联的值的断言抛出异常(例如缺少键异常),那么就可以了:不需要先测试键是否存在,然后测试其值。一次测试就足够了
如果字典是空的,则测试是无用的,因为此测试的目标似乎是验证某个键是否具有某个值
最后,使用某种类型的相等断言将给出更准确的错误消息:
Assert.Equal("ExpectedValue", dict["ExpectedKey"],
"Incorrect value for 'ExpectedKey'");
错误应该类似于“expected:ExpectedValue,actual:”。了解密钥的错误值可能会有所帮助 我认为这样做是有价值的,但你必须小心使用它。我还从事一个大型的多人项目,最近我们开始在单元测试策略中使用类似的方法 我们尝试对每个“执行路径”进行一个测试,并且我们有多个断言的测试用例。但是,我们在测试用例中使用致命和非致命断言,并且只有非致命断言用于具有多个断言的测试用例。致命断言也用于这些测试用例中(每个TC一个),以验证条件,如果条件失败,则断言其他任何内容都没有意义。这种方法帮助我们更快地定位错误,因为有时可能会发生多个断言 将其与自定义日志相结合,以提供有关故障的附加信息—测试和调试速度更快,实际上效率更高 但是,看看您的示例,我不确定“多个/可选断言”是否真的是一种好方法,因为您很可能不想反复测试这些基本功能(LoadDict(),n
Assert.Equal("ExpectedValue", dict["ExpectedKey"],
"Incorrect value for 'ExpectedKey'");