21

The question I want to ask you is quite wide but in the same time it's very concrete. First, I have to say, that I mostly interested in answers which are applicable in the .net environment.

Well, I want to increase the level of the code I produce. Now I mostly use the TDD and the static code analysis to ensure that my code is correct. Recently I've listened to Dino Esposito's speech about code contracts and now I want to use it in conjunction with other techniques. While listening to Dino I've also recalled the Debug.Assert() and Trace.Assert().

To be concrete I will ask several questions:

  • How should I write the contracts and unit tests to complement each other?
  • Should I use code contracts in every method or in public methods only?
  • Should I prevent the usage of Debug.Assert()? When it's OK to use them? (For example, notice that invariants in .net are checked only on public method/property exit. So, is it OK to make some checks in the middle of the method by simple Assert()?)
  • Could you please recommend me the open source project where all these techniques are properly used because a picture paints a thousand words?
Igor Soloydenko
  • 11,067
  • 11
  • 47
  • 90
  • My problem with `Debug.Assert` is that it never reaches production. You'll only find bugs with it in your dev/test environment. If such a bug that the assert would catch reaches the wild, it will make your repro harder. Using it instead of a release-available assert is an optimization step, and premature optimization is never good. – Merlyn Morgan-Graham Sep 04 '11 at 21:20
  • 1
    @Merlyn, AFAIK you can use the `Trace.Assert()` instead of `Debug.Assert()`. Here what MSDN says about it: > By default, the Debug.Assert method works only in debug builds. Use the Trace.Assert method if you want to do assertions in release builds. – Igor Soloydenko Sep 05 '11 at 07:36
  • Sounds better. I'd still consider throwing an exception the classic way (so you can get the bug reports), but at least you would be able to test that code path in all builds. *Edit*: Re-read the MSDN page, and it says it pops up a message box. This sounds like a nice soft error that can be reported (since it gives the stack trace). There's always the "if we're in this state, can the program state be trusted?" question. But that's more situational. – Merlyn Morgan-Graham Sep 05 '11 at 07:42
  • 1
    this post my help you - http://stackoverflow.com/questions/2549639/books-on-code-contracts-in-c-4-0 cheers. – Steoates Sep 05 '11 at 08:13
  • @Stephen Thanks. I'll take a look on materials in that post. – Igor Soloydenko Sep 05 '11 at 08:18
  • Bear in mind that to get the full Code Contracts experience, you need VS 2010 **Ultimate** edition, which is spendy. – AakashM Sep 05 '11 at 09:08
  • @Aakash: I thought Enterprise was enough (static checker). Does Ultimate add something? – H H Sep 05 '11 at 09:23
  • @Henk going on a memory of what I read in C# in depth 2e (which is not to hand). ALthough, I don't see Enterprise listed as an edition [here](http://www.microsoft.com/visualstudio/en-us/products/2010-editions/product-comparison) ? – AakashM Sep 05 '11 at 09:28
  • @Aakash I was running on memory too :) It's the Premium edition, see the 3 buttons here: http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx – H H Sep 05 '11 at 09:35

2 Answers2

4

You should start by studying the (rather good) manual for Contracts.

  • it has a chapter and sample code about unit test integration. Much more info if you follow the Pex links.
  • use contracts in all public members allways. For private members: sometimes.
  • you could still use Debug.Assert() but Contracts.Assert() would be the more logical choice.
  • sample projects... Don't know any. But do look at the contracts defined for the BCL.
H H
  • 263,252
  • 30
  • 330
  • 514
  • 1
    I haven't used code contracts, only heard of them. How does "For private members: sometimes" jive with "For example, notice that invariants in .net are checked only on public method/property exit" (from the OP)? Will those assertions/constraints ever be validated? – Merlyn Morgan-Graham Sep 04 '11 at 21:27
  • 4
    Merlyn, that rule applies to _Invariants_. The bulk of contracts is about Pre- and PostConditions (.Requires() and .Ensures()). – H H Sep 04 '11 at 21:32
4

I would fully embrace Contracts as in the preview blogs and by reading the longer pdf doc.

Contracts is not just for public functions. The big deal is that it provides a way for the compiler to reason about the code. So use it in all your functions as appropriate. That gives you the maximum benefit. Only using it in public functions is like saying you are only testing top level functions. Its wrong.

Your function test cases would mop up whatever logic still needs testing in the function after the Contract pre / post and invariant calls do their thing.

Be clear about the 3 usage scenarios, which one works for your code, and its issues. Ideally you can have them running in your production code and then scale back based on performance testing.

Make sure your generated docs include your contracts, its a nice benefit.

I also like the the DevExpress CodeRush and Refactor! Pro tools. They have specific refactorings for Contracts such as couple of clicks to turn input parameters into requires contracts etc. In addition they have some nice code analysis that will bump up your code quality in general.

You can peek at some code with Contracts here: https://searchcode.com/codesearch/view/14318515/

As for the whole best-practice enchilada all in one project. Well, I am looking at you Microsoft. Tsk.

Henk did a good job with the rest of your questions.

Dirk Bester
  • 1,791
  • 19
  • 21