Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caching result of setUp() using Python unittest

I currently have a unittest.TestCase that looks like..

class test_appletrailer(unittest.TestCase):
    def setup(self):
        self.all_trailers = Trailers(res = "720", verbose = True)

    def test_has_trailers(self):
        self.failUnless(len(self.all_trailers) > 1)

    # ..more tests..

This works fine, but the Trailers() call takes about 2 seconds to run.. Given that setUp() is called before each test is run, the tests now take almost 10 seconds to run (with only 3 test functions)

What is the correct way of caching the self.all_trailers variable between tests?

Removing the setUp function, and doing..

class test_appletrailer(unittest.TestCase):
    all_trailers = Trailers(res = "720", verbose = True)

..works, but then it claims "Ran 3 tests in 0.000s" which is incorrect.. The only other way I could think of is to have a cache_trailers global variable (which works correctly, but is rather horrible):

cache_trailers = None
class test_appletrailer(unittest.TestCase):
    def setUp(self):
        global cache_trailers
        if cache_trailers is None:
            cache_trailers = self.all_trailers = all_trailers = Trailers(res = "720", verbose = True)
        else:
            self.all_trailers = cache_trailers
like image 798
dbr Avatar asked Dec 31 '08 07:12

dbr


1 Answers

How about using a class member that only gets initialized once?

class test_appletrailer(unittest.TestCase):

    all_trailers = None

    def setup(self):
        # Only initialize all_trailers once.
        if self.all_trailers is None:
            self.__class__.all_trailers = Trailers(res = "720", verbose = True)

Lookups that refer to self.all_trailers will go to the next step in the MRO -- self.__class__.all_trailers, which will be initialized.

like image 179
cdleary Avatar answered Sep 30 '22 14:09

cdleary