我一直在阅读合同设计的帖子和例子,有些东西我似乎无法理解。在我看到的所有例子中,DbC用于一个简单的类,在后置条件下测试自己的状态(例如很多银行账户)。
在我看来,大多数情况下,当您调用类的方法时,它会将方法调用委托给其外部依赖项。我理解如何在单元测试中使用依赖性反转和关注方法外部行为的模拟对象检查具体方案,但是这如何与DbC和后置条件一起工作?
我的第二个问题必须涉及理解复杂的后置条件。在我看来,要为许多函数写出一个后置条件,你基本上必须为后置条件重新编写函数体,以了解新状态将是什么。有什么意义呢?
我确实喜欢DbC的概念,我认为它有很大的希望,特别是如果我找到一个经过验证的合同后我能弄清楚如何重现一些失败状态。在过去的几个小时里,我一直在阅读一些整洁的东西。在埃菲尔自动测试生成。我目前正在努力改进我在C ++开发中的流程,但如果我能弄清楚如何不失去我在当前项目中所做的所有基础,我愿意学习新东西。感谢。
答案 0 :(得分:1)
但这如何与DbC和 后置条件?
每个功能基本上都是其中之一:
这个想法是你应该检查关于函数结果的任何后置条件,这些后置条件超出了所有被调用函数的后置条件的并集。
你基本上要重写 你身体的功能 后期条件要知道什么是新的 国家将是
反过来考虑一下。是什么让你首先编写这个功能?你在追求什么?这可以在一个比函数体本身更简单的后置条件中表达吗?后置条件通常使用查询(C ++中的const
函数),而正文通常组合命令和查询(修改对象的方法和仅从中获取信息的方法)。
在一些的情况下,是的,你会发现你可以用后置条件添加很少的值。在这些情况下,编写一堆测试通常就足够了。
另见:
答案 1 :(得分:1)
合同级别的代表团
大多数时候你打电话给 一个类的方法,它做得更多 工作委托方法调用它 外部依赖
至于第一个问题:函数/方法的实现可能会调用许多其他函数/方法,但如果代码的设计者有一个清醒的头脑,这并不意味着<调用者的em> specification 是被调用者规范的串联。对于调用许多其他方法的方法,如果方法完成精确且定义明确的任务,则规范的大小可以保持包含。如果整个系统设计得很好,它应该是什么。
从运行时断言检查的角度来看,您显然是在问自己的问题。在这种情况下,上述内容可能表示为“你不需要在调用者的后置条件下重新检查所有被调用者都尊重他们各自的合同。这些检查已经在每次通话时都可以进行。在来电者的后期条件下,只检查来电者的功能可见的结果。“
了解复杂的后置条件
您可能会发现此"ACSL by example" document很有趣(尽管可能与您习惯的不同)。它包含许多C函数的正式合同示例。合同的语言用于静态验证而不是运行时检查,具有所需的所有优点和缺点。它们比你提到的“银行账户”稍微复杂一些 - 这些功能实现了真正的算法,虽然简单。该文档通过引入经过深思熟虑的辅助谓词(在艾菲尔中称为queries来保持合同的简短性和可读性,正如丹尼尔在答案中指出的那样。)