如何使用代码合同进行单元测试

bri*_*ler 12 .net code-contracts c#-4.0

使用.NET 4.0代码合同进行TDD的最佳实践建议是什么?

我特别想到,我的问题是,鉴于TDD的一个要点是允许代码自我记录并且合同现在提供了文档的一部分,代码合同是否应该像其他代码一样进行测试?

Mat*_*ias 11

这取决于您使用合同的方式以及您正在开发的应用程序类型.

首先:你肯定不希望测试(断言和后置条件Contract.Assert,Contract.Assume,Contract.EnsuresContract.EnsuresOnThrow)separetly.我认为这样做没有实际价值 - 因为它们已经在运行时由重写器验证,即使没有测试,您也会发现故障非常快.
但是,在经过良好测试的应用程序中,即使在无效输入上,也不会出现后置条件或断言失败.因此,如果所有测试(甚至是测试处理无效数据的测试!)在没有单个后置条件/断言失败的情况下通过,那么您的后置条件和断言可以被视为"已测试".
为此,您可能希望在测试中使用"Assert.Fail"处理ContractFailed事件.

现在,"有趣"的部分是前提条件:
你在开发图书馆吗?然后,如果您的时间/预算允许,那么您应该测试它们(更糟糕的是不测试实际逻辑).
特别是,如果您使用"Contract.Requires <E>"重载将导致合同失败的特定异常,您应该像使用"if-throw"-constructs一样测试它们.

如果你不是在编写库,我不会说测试前置条件是非常必要的 - 它们不是真正的业务需求,而是调试的帮助器.如果一个参数是,那么
为每个ArgumentNullException方法编写一个单元测试都会变得非常无聊null.
如果您在方法中忘记了此验证代码(意思是:特定的Contract.Requires),您可能也会忘记单元测试.因此,参数验证测试为您的(非库)代码带来的附加值对连接值来说非常低.

总结一下:不要测试后置条件和断言.测试前提条件 - 但仅限于库(以及代码中可能像库一样使用的部分).