views:

133

answers:

6

Is it too bad to write a really long (more than 200 lines) test method? Or should I break it up into smaller-methods?

+11  A: 

You shouldn't (on the whole) create any method that's 200 lines long. If you can break it up, do.

What are you doing in 200 lines? Unit testing should be testing small units of code. Are those 200 lines predominantly assertions? If so, then that might be OK.

The key question is - can someone understand what the method's doing quickly, or is it hard to get your head around?

"Programs should be written primarily to be read by people, and only incidentally to be run by machines." (Abelson & Sussman, Structure and Interpretation of Computer Programs)

Dominic Rodger
200 lines of assertions (I've never seen or written anything that makes anywhere near that number of assertions in one test). If that was the case then it sounds like the test is an Eager Test- http://xunitpatterns.com/Obscure%20Test.html#Eager%20Test
RichardOD
@RichardOD - almost certainly agree, but it's difficult to put a line-count limit on such things. That documentation you linked to looks great - put it in your answer and I'll vote it up!
Dominic Rodger
assert(1, 1 + 0); assert(1, 0 + 1); assert(2, 2 + 0); assert(2, 1 + 1); assert(2, 0 + 2); .... although at that point, I think another fundamental problem has been (or should be) revealed.
pst
Actually the book is great (that and the Art of Unit testing are my 2 fav unit testing books)! I've upvoted as the rest of your answer is good.
RichardOD
I am testing different update scenarios so I am generating data sets, calling the update method (test target) and then following it with assertions. It is around 15 lines for every single update scenario. and I have at least 20 update scenarios
a b
@a b - could you break each update scenario into a separate method? Do they depend on each other?
Dominic Rodger
they do depend on each other
a b
OK, then break them up as far as you can, and no further (e.g. if the first 3 scenarios can be broken out, break them out). Don't sweat it too much.
Dominic Rodger
+4  A: 

200 lines sounds too long. A unit test method is just like any other method. You should use the "Extract Method" refactoring where possible. This will increase the readability of your code.

Edit- as your test is long it could also exhibit a number of test smells like Eager Test.

Usually in the tests that I write I like to quickly see Arrange/Act/Assert. If you've got this over 200 lines it's probably difficult to tell which bit is where.

RichardOD
+1  A: 

I would question most any method that came close to 200 lines. Breaking it up should add to intrinsic code readability and could possibly help to identify areas of failure more precisely or otherwise start purring like a cat: of course this depends on the method in question, the language and testing framework used.

Oh, and it likely can :-)

pst
+1  A: 

Long methods are undesirable. They are often an indication that a method is doing too much.

The same applies to unit-tests, if not more so. Ideally, you should be able to immediately figure out what a unit-test is testing by looking at it.

Mitch Wheat
+1  A: 

One unit-test should test one thing, and you should avoid logic in your unit test in order to avoid having to writing code that tests your unit tests.

Having said that, if most of those 200 lines are setup code to ensure a particular state of your data in order to reproduce a hard-to-test edge case bug, then that might be the only way to do it.

But you should, if possible, try to minimize the number of lines in unit tests. They quickly become very fragile (breaks easily upon modifications) when they are long.

Lasse V. Karlsen
True, but you can (I would) extract the Arrange part out into its own method so the overall test is easy to read.
RichardOD
Definitely, if for no other reason than your unit-test having "Arrange(); Act(); Assert();" type names on things.
Lasse V. Karlsen
I've never seen 200 lines to get a particular state but I have seen 50 or 60 lines to do so. Honestly though, can that really be a _unit_ test rather than a _functional_ test?
sal
+1  A: 

The fact that you ask if you should break it up indicates that you can break it up. I think that especially unit tests should be as small as possible and each one testing only one aspect of your software.

Georg