如何将防御性编程技术结合起来?

21

我想问你的问题相当广泛,但同时也非常具体。首先,我必须说,我最感兴趣的是适用于 .net 环境的答案。

好吧,我想提高我所编写代码的水平。现在我主要使用 TDD 和静态代码分析来确保我的代码是正确的。最近我听了 Dino Esposito 的关于代码协定的演讲,现在我想将其与其他技术结合使用。在听 Dino 的演讲时,我还回忆起了 Debug.Assert()Trace.Assert()

为了更具体,我会问几个问题:

  • 我应该如何编写契约和单元测试来相互补充?
  • 我应该在每个方法或只在公共方法中使用代码协定?
  • 我应该防止使用 Debug.Assert() 吗?什么情况下可以使用它们?(例如,注意到在 .net 中不变量仅在公共方法/属性退出时才会被检查。因此,通过简单的 Assert() 在方法中间进行一些检查是否可以?)
  • 您能否推荐给我一个开源项目,其中所有这些技术都得到了正确使用,因为图画千言万语呢?

我的问题是Debug.Assert永远不会到达生产环境。你只能在开发/测试环境中找到它的错误。如果这样一个断言可以捕获的错误到达了线上环境,那么它将使您的重现变得更加困难。使用它而不是可用于发布的断言是一种优化步骤,而过早的优化从来都不是好事。 - Merlyn Morgan-Graham
1
@Merlyn,据我所知,您可以使用Trace.Assert()代替Debug.Assert()。 这是MSDN对此的解释:
默认情况下,Debug.Assert方法仅在调试版本中起作用。如果要在发布版本中进行断言,请使用Trace.Assert方法。
- Igor Soloydenko
1
这篇文章可能对您有所帮助 - https://dev59.com/7EzSa4cB1Zd3GeqPqeWI祝好。 - Steoates
@Stephen 谢谢。我会查看那篇帖子中的材料。 - Igor Soloydenko
请注意,要完全体验代码合约的功能,您需要使用代价昂贵的 VS 2010 Ultimate 版本。 - AakashM
显示剩余4条评论
2个回答

4

您应该从学习(相当不错的)Contracts手册开始。

  • 它有一章关于单元测试集成和示例代码。如果您跟随Pex链接,将会得到更多信息。
  • 在所有公共成员中始终使用合同。对于私有成员:有时候使用。
  • 您仍然可以使用Debug.Assert(),但Contracts.Assert()是更合适的选择。
  • 样例项目... 不清楚。但请查看为BCL定义的约束条件。

1
我从未使用过代码契约,只是听说过。 "对于私有成员:有时" 如何与“例如,请注意,在 .net 中,不变式仅在公共方法/属性退出时进行检查”(来自 OP)相一致?那些断言/约束是否会被验证? - Merlyn Morgan-Graham
4
Merlyn,这个规则适用于“不变量”。合同的大部分内容是关于前置条件和后置条件(.Requires()和.Ensures())的。 - H H

4
我会完全接受合同,就像预览博客和阅读更长的pdf文档所述。
合同不仅适用于公共函数。重要的是它提供了一种让编译器推理代码的方式。因此,在适当的情况下在所有函数中使用它。这将为您带来最大的好处。仅在公共函数中使用它就像说您只测试顶级函数一样。这是错误的。
您的功能测试用例将清理函数中Contract前/后和不变式调用后仍需要测试的任何逻辑。
明确三个用法场景,哪一个适用于您的代码以及其问题。理想情况下,您可以在生产代码中运行它们,然后根据性能测试进行缩减。
确保您生成的文档包括您的合同,这是一个很好的福利。
我还喜欢DevExpress CodeRush和Refactor!Pro工具。它们具有特定的重构合同,例如将输入参数转换为要求合同等的几次点击。此外,它们还有一些不错的代码分析,可以提高您的代码质量。
您可以在此处查看一些使用Contracts的代码: https://searchcode.com/codesearch/view/14318515/

关于整个最佳实践大杂烩的项目。嗯,我看着你微软。唉。

Henk在回答你其他问题方面做得很好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接