views:

129

answers:

6

So I see that Assert has dozens of methods that seem to do essentially the same thing.

Assert.IsFalse(     a == b );
Assert.IsTrue(      a != b );
Assert.AreNotEqual( a,   b );

Why? Is it just to be more explicit? When should the various methods be used? Is there an offical best practices document?

+7  A: 

Short answer: For readability.

Slightly longer answer:

Your tests are also code, and in terms of intent are as important as the code you are testing. As such, you want to make the intent of the test as clear as possible. Sometimes that means you use IsFalse, sometimes it means using IsTrue.

Oded
"You[r] tests are also code... you want to make the intent of the test as clear as possible"...to play devils advocate: Then why isn't it standard practice to create and use isEqual, isNotEqual, etc in normal code? (I'm aware that Equals exists, but it's less commonly used)
Catskul
@Catskul: Testing is all about maintainability. We do use == and != for equality and inequality in regular code. How often do you see: "if (a == (!b) )" instead of "if (a != b)"?
Reed Copsey
@Reed, "!b" may not have any sense. Asserts AFAIK must always reduce to true/false.
Catskul
@Catskul: ...but when it does make sense, would you write it that way? Of course not - you'd use the appropriate != method instead.
Reed Copsey
@Catskul: If you don't like that case - how often do you write: "if (!(a == b))" instead of "if (a != b)"? There's a reason we use the separate methods in the language...
Reed Copsey
@Reed, but again playing devils advocate: If it's true that "AreNotEqual" is clearer, then why shouldn't we be using it in all of our code rather than just in unit tests?
Catskul
+4  A: 

Those three methods have three different, specific goals. The goal of testing is to provide clear verification and validation of your code. By using the most clear and specific method possible, you're making your test the smallest test possible, with the most specific, clear meaning possible.

This helps because it adds clarity - you can see, specifically, what a test is supposed to do in a more declarative nature, where using the same method for multiple testing scenarios, which each have a different meaning, requires more understanding of the code itself, instead of the nature of the test.

In this case, the third is the (only) appropriate one to use. However, if you had this situation, you'd use a different one, for example:

Assert.IsTrue( myClass.MethodThatReturnsTrue() );

You should use the method that provides the most clarity as to your goal - if you're checking two values for equality, use Assert.IsEqual, if you're checking a boolean to verify that it's false, use Assert.IsFalse. This makes the error reports meaningful and understandable.

Reed Copsey
You've asserted(no pun intended) that they do very different things, but haven't offered an explanation.
Catskul
@Catskul: I reworded - does that help?
Reed Copsey
+3  A: 

The difference between IsFalse and IsTrue is readability. AreNotEqual allows a better error message to be presented when the test fails. IsTrue for example will just tell you that the answer was supposed to be true and was really false. AreNotEqual will show the two values that were compared in its error message.

Daniel Straight
IMO, this is the best/most concise answer I've seen so far. Top answer is missing that it gives a more informative error message.
Catskul
Brett Daniel
+1  A: 

It makes the errors easiest to read; use the one that matches your code most closely.

In this case, use #3.

Dean J
+1  A: 

Because you can overload the == and != , thats why.

Brian Leahy
... and you can write your own Equals method. AFAIK it's not clear that these Assert methods don't themselves rely on those operators or the Equals method for that matter.
Catskul
+1  A: 

It's called a "Fluent Interface"... and makes things more readable in the opinion of many.

Nick