views:

66

answers:

2

I'm somewhat new to writing tests. I've find myself struggling with keeping my setUp's clean and concise, instead trying to accomplish too much with an uber-setUp.

My question is, how do you split up your testing?

Do your tests include one or two lines of independent step code?

def test_public_items():
    item1 = PublicItem()
    item2 = PublicItem()
    assertEqual(public_items, [item1, item2])

or do you factor that into the setUp no matter what?

If that's the case, how do you deal with test class separation? Do you create a new class when one set of tests needs a different setUp then another set of tests?

+3  A: 

I believe you've hit a couple of anti-patterns here

  • Excessive Setup
  • Inappropriately shared fixture.

The rule of thumb is that all tests in a particular test fixture should need the code in the Setup() method.

If you write a test() that needs more or less setup that what is currently present, it may be a hint that it belongs to a new test fixture. Inertia to create a new test fixture.. is what snowballs the setup code into one big ball of mud - trying to do everything for all tests. Hurts readability quite a bit.. you can't see the test amid the setup code, most of which may not even be relevant for the test you're looking at.

That said it is okay to have a test have some specific setup instructions right in the test over the common setup. (That belongs to the first of the Arrange-Act-Assert triad). However if you have duplication of those instructions in multiple tests - you should probably take all those tests out to a new test fixture, whose

setup_of_new_fixture = old_setup + recurring_arrange_instruction
Gishu
I'm accepting your answer because you clearly identified classes with fixtures. This clarifies a lot.
Soviut
+1  A: 

Yes, a text fixture (embodied in a class) should exactly be a set of tests sharing common needs for set-up and tear-down.

Ideally, a unit test should be named testThisConditionHolds. public_items is not a "condition". Wherever the incredibly-black-magic public_items is supposed to come from I'd be writing tests like:

def testNoPublicItemsRecordedIfNoneDefined(self):
    assertEqual([], public_items)

def testOnePublicItemsIsRecordedRight(self):
    item = PublicItem()
    assertEqual([item], public_items)

def testTwoPublicItemsAreRecordedRight(self):
    item1 = PublicItem()
    item2 = PublicItem()
    assertEqual([item1, item2], public_items)

If public_items is a magical list supposed to be magically populated as a side effect of calling a magic function PublicItem, then calling the latter in setUp would in fact destroy the ability to test these simple cases properly, so of course I wouldn't do it!

Alex Martelli
My example was just to show "additional work" being done within the test itself. I was wondering if this was considered acceptable.
Soviut