例如,这文章介绍了他们。
优点是什么?
静态分析看来很酷,但在同一时间,它会阻止传递null作为单元测试参数的能力。 (如果您是文章是在本例中)
而在单元测试的主题 - 给定的东西怎么现在肯定没有一点代码合同,如果你已经练习自动化测试?
更新
已经打了代码契约,我有点失望。 例如,基于接受的答案代码:
public double CalculateTotal(Order order)
{
Contract.Requires(order != null);
Contract.Ensures(Contract.Result<double>() >= 0);
return 2.0;
}
对于单元测试,你仍然需要编写测试,以确保空无法通过,结果大于或等于零,如果合同是商业逻辑 。 换句话说,如果我是删除第一份合同,没有测试会打破,除非我曾专门针对此功能的测试。 这是基于不使用内置到更好的静态分析的Visual Studio(最终等)版本但是。
从本质上讲,他们都归结为传统的书写if语句的另一种方式。 实际使用我的经验TDD,用代码契约说明了为什么,我该怎么去了解它。
我不认为单元测试和合同相互干扰多,如果有什么合同,应当帮助单元测试,因为它消除了需要增加繁琐的重复测试的参数无效。 合同规定可以从功能期待最小,而单元测试尝试验证的实际行为为一组特定的输入。 考虑这个人为的例子:
public class Order
{
public IEnumerable Items { get; }
}
public class OrderCalculator
{
public double CalculateTotal(Order order)
{
Contract.Requires(order != null);
Contract.Ensures(Contract.Result<double>() >= 0);
return 2.0;
}
}
显然,代码满足合同,但你仍然需要单元测试,以验证它实际上表现为你所期望的。
优点是什么?
比方说,你要确保一个方法永远不会返回null
。 现在,单元测试,你必须写一堆的测试情况下,你调用该方法具有不同的输入和验证输出不为空。 麻烦的是,你无法测试所有可能的输入。
随着代码的合同,你只需要声明的是,方法从不返回null
。 然后,静态分析会抱怨,如果它无法证明。 如果它不抱怨,你知道你的说法是对所有可能的输入是正确的。
更少的工作,完美的正确性的保证。 有什么理由不喜欢?
合同允许你说什么代码的实际目的是,而不是让任何代码的功能与任何随机参数都交给它站立从来看编译器,或者代码的下一个读者的角度定义。 这显著更好地使静态分析和代码优化。
例如,如果我声明一个整数参数(使用合同符号),以在1至10范围内,以及我在我的函数的局部阵列中声明的相同的大小,由所述参数索引,编译器可以告诉没有下标误差的可能性,从而产生更好的代码。
你可以说,空是在合同有效的值。
单元测试的目的是动态地验证该代码实现具有任何所述目的。 仅仅因为你已经写了一个功能的合同,并不意味着代码这样做,或静态分析可以验证代码做到这一点。 单元测试不会消失。
那么它不会与普通的单元测试干扰。 但是,当我看到你所提到的一些关于TDD。
如果我想它从这个角度我想这可能/可能与标准一个改变的过程
- 创建方法(只是签名)
- 创建单元测试 - >执行测试
- 运行测试:让它失败
- 实施方法,劈到最后只是为了它的工作
- 运行测试:看它传递
- 重构你的(可能是混乱的)方法体
- (重新运行测试只是为了看看你不破什么)
这将是真的很辛苦,功能全面的单元测试过程。 在这样的背景下我想你可以插入第一和第二点之间的代码像合同
- 创建方法(只是签名)
- 插入用于所述方法的输入参数代码合同
- 创建单元测试 - >执行测试
- ...
优点我目前看到的是,你可以写,你会不会有,因为一些已经被你定义的合同考虑,以检查每一个可能的路径感更容易单元测试。 它只是给你额外的检查,但它不会取代单元测试,因为总是会有在代码中更多的逻辑,即必须与单元测试照常进行测试多个路径。
编辑
之前我没有考虑另一种可能性是添加代码合约重构的一部分。 基本上为保证事情的另一种方式。 但是,这会在一定程度是多余的,因为人们不喜欢做重复的东西...