Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test with Code Contracts

What is the best practice recommendation for doing TDD with .NET 4.0 Code Contracts?

I suppose specifically, my question is that given that one point of TDD is to allow the code to be self documenting and the contract now provides a part of the documentation, should code contracts be tested in the same way as other code?

like image 488
satnhak Avatar asked May 01 '11 17:05

satnhak


1 Answers

This depends on how you are using contracts and what kind of application you are developing.

First of all: You certainly don't want to test assertions and postconditions (Contract.Assert, Contract.Assume, Contract.Ensures and Contract.EnsuresOnThrow) separetly. I see no practical value in doing so - as they are already verified during runtime by the rewriter, you will find failures very fast even without tests.
However, in a well tested application, no postcondition or assert should fail - even on invalid inputs. Thus, if all your tests (even the ones testing handling of invalid data!) pass without a single postcondition/assertion-fail, your postconditions and assertions can be seen as "tested".
For this, you might want to handle the ContractFailed event using an "Assert.Fail" within your tests.

Now the "interesting" part are the preconditions:
Are you developing a library? Then, you should definitely test them if your time/budget allows this (it's worse not testing the actual logic).
Especially, if you are using the "Contract.Requires<E>" overload which will throw a specific exception on contract failures, you should test them like regular parameter validation using "if-throw"-constructs.

If you are not writing a library, I wouldn't say that testing preconditions is really necessary - they are no real business requirement but rather a helper for debugging.
And it can get really boring to write a unittest for every ArgumentNullException a method should throw if a parameter is null.
If you forget this validation code (meaning: The specific Contract.Requires) inside your method, you will probably forget the unit-test, too. Therefore, the additional value a parameter-validation-test brings to your (non-library-)code is very low to the connected value.

To sum it up: Don't test postconditions and asserts. Do test preconditions - but only on libraries (and maybe parts of your code which are used like libraries).

like image 89
Matthias Avatar answered Nov 03 '22 03:11

Matthias