Assert.That vs Assert.True

2020-06-30 09:18发布

问题:

What to prefer:

Assert.That(obj.Foo, Is.EqualTo(true))

or

Assert.True(obj.Foo)

For me, both asserts are equivalent, so which one should be prefered?

回答1:

In this particular case, there is no difference: you will see the output of roughly the same level of detail (i.e. it tells you that something that was expected to evaluate to true has evaluated to false). Same goes for

Assert.IsTrue(obj.Foo);

and

Assert.That(obj.Foo, Is.True);

Your team should pick one style of assertions, and stick with it throughout all your tests. If your team prefers the Assert.That style, then you should use Assert.That(obj.Foo, Is.True).



回答2:

Assert.That is called the constraint-based model. It's flexible because the method takes a parameter of IConstraint type. This means you can structure your code with a more generic hierarchy or calling structure, passing in any old IConstraint. It means you can build your own custom constraints

That's a design issue. As everyone is saying, no matter what you still need to provide decent error message feedback.



回答3:

So ok, you executed your test suite on CI server and unfortunately, one of them failed. You open the logs and see next message

BusinessLogicTests.LoginTests.UserAutoLoginTests failed: expected true but was false

Now how on earth would you get what happened wrong with this tests, if all the information you see, is that somewhere in AutoLoginTests bool was expected true, but received false? Now you need to go to the source file of your tests cases and see, what assertion failed. You see

Assert.True(obj.Foo)

Amazingly.. it's still hard to tell what's wrong, only if you developed this module 1 hour ago. You still need to go deeper into tests sources and probably production sources or even debug your code, so that you can at last figure out, that you misspelled a variable inside function call or used wrong predicate to filter registered users. Thus you blocked immediate feedback from tests, which is very valuable.

My point is that it's dosn't matter how fluent your assertions are (which are also relevant), but what information you expose in case of failing tests and how fast can you get the underlying reason of failure, even if you worked a long time ago with this functionaluty



回答4:

This is a bit nit-picky but IMHO I think that in this case Assert.That is unnecessarily verbose and can therefore be regarded as obfuscation. In other words, Assert.True is a little cleaner, more straightforward and easier to read and therefore comprehend.

To get a little more nit-picky I would suggest using the Assert.IsTrue API instead of Assert.True since, again IMHO, IsTrue "reads" better.