[TIP] setUp and tearDown behavior

Michael Foord fuzzyman at voidspace.org.uk
Tue Jan 19 06:43:05 PST 2010


On 19/01/2010 14:32, John Arbash Meinel wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Michael Foord wrote:
>    
>> On 19/01/2010 13:53, Olemis Lang wrote:
>>      
>>> [snip...]
>>>        
>>>> In case this is expected, is there a way to do it just once for all the
>>>> methods?
>>>>
>>>>
>>>>          
>>> Using standard `unittest` module ? well ... no.
>>>
>>>
>>>        
>> Well - you can make setup *effectively* only run the first time using a
>> class attribute:
>>
>>
>> class SomeTest(unittest.TestCase):
>> doneSetup = False
>> def setUp(self):
>> if not self.__class__.doneSetup:
>> self.__class__.doneSetup = True
>> self.setUpClass()
>> ...
>>      
> ^- just mentioning that using it this way will run setup for each child
> class. Which may be what you want, or may not.

Yes, I deliberately showed code using self.__class__ so that this would 
be the case.

> If you want to run it one
> time across all inherited tests, then you need to use:
>
> def setUp(self):
>    if not SomeTest.doneSetup:
>      ...
>
> At least, that is how I understand setattr(), I could be wrong...
>
>    
>> Making tearDown only run the *last* time is a bit harder (you could hack
>> it in with a counter in setUp and only execute tearDown when the counter
>> == number of test methods). Builtin support for class level fixtures in
>> unittest would be good, even if they are ripe for abuse (shared state
>> between fixtures).
>>
>> All the best,
>>
>> Michael Foord
>>
>>
>>      
> The problem with a simple counter is that the counter always stays at 0.
>
> setUp() +1 = 1
> test1()
> tearDown() -1 = 0
>    
If you're using a counter to count test methods run *why on earth* would 
you decrement in tearDown? :-)

Michael

> setUp() +1 = 1
> test2()
> tearDown() -1 = 0
>
> etc.
>
> I believe we handle it using "startTestRun()" and "stopTestRun()" but
> those are defined for the whole test suite, not for a subset.
>
> A different possibility with the "test_suite()" or "load_tests()"
> paradigm, is that you can create a custom TestSuite instance that
> overloads run() (I believe) to do something like:
>
> class MySuite(unittest.TestSuite):
>
>   def run(self):
>     self.doSuiteSetup()
>     unittest.TestSuite.run(self)
>     self.doSuiteTearDown()
> ...
>
> John
> =:->
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (Cygwin)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
>
> iEYEARECAAYFAktVwm0ACgkQJdeBCYSNAAMVjQCfdhfc0ft25VHqpEaWCEECcNYj
> 1C4An0poeOfzfcP8HeYKzYOeITRDw3QJ
> =QtaF
> -----END PGP SIGNATURE-----
>    


-- 
http://www.ironpythoninaction.com/




More information about the testing-in-python mailing list