[unittest] Run setUp only once

Jean-Paul Calderone exarkun at divmod.com
Tue Jul 29 20:28:02 CEST 2008


On Tue, 29 Jul 2008 20:12:14 +0200, Nikolaus Rath <nikolaus at rath.org> wrote:
>Jean-Paul Calderone <exarkun at divmod.com> writes:
>> On Tue, 29 Jul 2008 19:26:09 +0200, Nikolaus Rath <nikolaus at rath.org> wrote:
>>>Jean-Paul Calderone <exarkun at divmod.com> writes:
>>>> On Tue, 29 Jul 2008 16:35:55 +0200, Nikolaus Rath <nikolaus at rath.org> wrote:
>>>>>Hello,
>>>>>
>>>>>I have a number of conceptually separate tests that nevertheless need
>>>>>a common, complicated and expensive setup.
>>>>>
>>>>>Unfortunately, unittest runs the setUp method once for each defined
>>>>>test, even if they're part of the same class as in
>>>>>
>>>>>class TwoTests(unittest.TestCase):
>>>>>    def setUp(self):
>>>>>        # do something very time consuming
>>>>>
>>>>>    def testOneThing(self):
>>>>>
>>>>>
>>>>>    def testADifferentThing(self):
>>>>>
>>>>>
>>>>>which would call setUp twice.
>>>>>
>>>>>
>>>>>Is there any way to avoid this, without packing all the unrelated
>>>>>tests into one big function?
>>>>>
>>>>
>>>>    class TwoTests(unittest.TestCase):
>>>>        setUpResult = None
>>>>
>>>>        def setUp(self):
>>>>            if self.setUpResult is None:
>>>>                self.setUpResult = computeIt()
>>>>
>>>>        ...
>>>>
>>>> There are plenty of variations on this pattern.
>>>
>>>
>>>But at least this variation doesn't work, because unittest apparently
>>>also creates two separate TwoTests instances for the two tests. Isn't
>>>there some way to convince unittest to reuse the same instance instead
>>>of trying to solve the problem in the test code itself?
>>>
>>
>> Eh sorry, you're right, the above is broken. `setUpResult` should be
>> a class attribute instead of an instance attribute.
>
>Yeah, well, I guess that would work. But to me this looks really more
>like a nasty hack.. isn't there a proper solution?
>

How is it a nasty hack?  It's a straight-forward implementation of shared
state, which is what you said you wanted.

If you prefer, you could keep the state somewhere else - like by applying
a memoizer to `computeIt´ and just calling it unconditionally in `setUp´.

Jean-Paul



More information about the Python-list mailing list