Just like the question asks, is there a need to add Debug.Assert into your code if you are writing unit tests (which has its own assertions)? I could see that this might make the code more obvious without having to go into the tests, however it just seems that you might end up with duplicated asserts. It seems to me that Debug.Assert
was helpful before unit-testing became more prevalent, but is now unnecessary. Or, am I not thinking of some use case?
-
2I think this is answered in programmers.stackexchange.com/questions/18288/…– Ben CottrellApr 15, 2012 at 14:30
-
@BenC Thanks for the link. I liked Berin's answer relating Design-By-Contract. That actually clicked the most with me..and made me wonder why I didn't see that in the first place :-p– Justin PihonyApr 15, 2012 at 16:40
3 Answers
Assertions make assumptions explicit. Well-written unit tests do the same, but in an entirely different place.
Therefore, assertions, interspersed into the logic, help document the code and make it more understandable. This is how I use assertions. This is helpful in particular when implementing algorithms from theoretical descriptions, which usually offer the assertions as part of a correctness proof.
In a way, unit tests and assertions are two sides of the same coin: unit tests attempt to ensure correctness by trial, while assertions attempt to ensure it by proof.
Furthermore, assertions may help debug such algorithms because they offer sub-unit resolution, if you will. Unit tests on the other hand are inherently constrained to a coarser resolution. They can’t tell you anything about the internal state of an algorithm. Having small units helps but isn’t always feasible.
-
+1 but I'm not seeing how assertions are proofs. They are still only being tested on specific cases. Apr 15, 2012 at 14:48
-
@Winston If the assertions are rigorous then they do constitute the complete proof. A partial correctness proof for an algorithm is formulated in assertions on the algorithm state. You do not assert specific cases, you (should, and easily can) provide generality. Apr 15, 2012 at 15:01
-
-
I've never seen assertions with sufficient rigor to constitute a proof. Apr 15, 2012 at 17:16
-
More to the point, assertions are made generally, but they are only verified for specific cases. I'm still not seeing a connection to proofs. Apr 15, 2012 at 17:30
Unit tests assert correctness for specific inputs (the test inputs).
Contract assertions (or debug assertions) assert correctness for any given input.
If you want your code to be safer then the combination between the two will produce better results.
As others have already mentioned, a combination of assertions and unit tests will document your code better and help to ensure correctness, but they are used for different reasons: assertions verify the internal state of a codebase while unit tests verify the external behavior of a codebase.
Also keep in mind that assertions and unit tests can be executed separately as well as together. Here are a few scenarios:
- Building the code in the IDE and running it in
Debug
configuration will only execute assertions. - Executing unit tests in
Debug
configuration will also execute assertions. - Executing unit tests in
Release
configuration will not execute assertions.
Therefore, it helps to have assertions scattered throughout the codebase that will be executed in Debug
configuration as well as unit tests that can be executed separately in either Debug
or Release
configuration.