views:

68

answers:

3

Is having more than one assert per test a really bad smell? I usually try to follow the “arrange, act, assert” pattern as well as the single assert per test guideline. I think having clean, small, isolated tests is pure awesomeness. For the most part I manage to do this. However, sometimes I find myself asserting “pre-conditions” right after my arrange like so:

'arrange:
'pre-conditions:     
     Assert the arrange worked
'act:
'assert:

Is my test testing too much? Is it caring about things it shouldn’t care about? I’d love to hear some opinions on this.

A: 

I think having to use Assert to validate the setup is suboptimal, as it muddies the results (it might be hard to figure out what you're testing, if just looking at the output).

I recognize that there are times when this is necessary, or you just want to make sure that everything is being tested in the way you intend.

My practice is to use Debug.Assert (in C#) for this purpose, so that the setup validation does not become part of the test output.

You might be able to achieve the same in other languages by throwing an exception if the setup does not put the system into an expected state.

Different test runners may handle this differently, so you should make sure that this approach has the desired effect (tests fail, but no extra report output as long as the Debug.Assert passes or no exception thrown).

Jay
All these are great answers. However, I'm choosing Jay's because I like how Debug.Assert reads in the test. Thanks again.
Buzzer
+1  A: 

As I said here, I think perhaps our best practice should be, not Arrange-Act-Assert, but rather Arrange-Assume-Act-Assert. That before Acting, we assert that the desired result of the Action is not already in effect. This isn't exactly the same as what you are asking; generally I don't think it's important to verify the setup, because setup errors tend to manifest themselves pretty "loudly" in any case; but it's a good reason to have a second assert in the test.

Carl Manaster
A: 

I would not use a vanilla "Assert" for that but rather Assert.Inconclusive (MSTest)¹. The test has not failed, so you don't want to fail the test run.

1) Assume in JUnit and NUnit I believe.

mlk