简体   繁体   中英

Python unittest - using setupclass, and more than one setup / takedown?

I understand that setUpClass/tearDownClass methods are called once for a class, and setUp()/tearDown() are called before/after each unit test. See the code snippet below for this standard setup:

class Example(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        do_expensive_setup_of_immutable_objects_used_by_all_tests()

    def setUp(self):
        do_setup_before_each_test()

    def test1(self):
        do_test1_stuff()

    def test2(self):
        do_test1_stuff()

    def tearDown(self):
        do_teardown_after_each_test()

    @classmethod
    def tearDownClass(cls):
        do_teardown_of_immutable_objects_used_from_all_tests()

However, I would like some unit tests to have a different setUp() and tearDown() from other unit tests. What would be considered a good test structure to achieve this functionality? What options do I have? I am inexperienced in Python and would like to know a good style to adopt for writing unit tests involving expensive setUp() procedures.

Maybe this is what @Klaus means?

import unittest


class TestA(unittest.TestCase):
    def setUp(self):
        print "Setup # 1"

    def test1(self):
        print "Doing test1"

class TestB(unittest.TestCase):
    def setUp(self):
        print "Setup # 2"

    def test2(self):
        print "Doing test2"


if __name__ == "__main__":
    unittest.main()

Alternatively you can change setup based on the method name.
Although this might be a bit more of a pain to maintain.

class TestA(unittest.TestCase):
    def setUp(self):
        if self._testMethodName == "test1":
            print "Setup # 1"
        elif self._testMethodName == "test2":
            print "Setup # 2"

    def test1(self):
        print "Doing test1"

    def test2(self):
        print "Doing test2"


if __name__ == "__main__":
    unittest.main()

Both produce the same output:

Output:
Setup # 1
Doing test1
.Setup # 2
Doing test2
.
----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

EDIT: Sorry, I don't think I fully understand but here is my attempt at implementing your comment. My approach here is to reapply BaseTest.setUp() rather than try to keep it intact as you described.
TypeOneTests and TypeTwoTests inherit BaseTest and they call BaseTest 's setUp function inside their own using super(...)

class BaseTest(unittest.TestCase):
    def setUp(self):
        print "BaseTest setUp"

    def tearDown(self):
        print "BaseTest tearDown"

    # you could add tests here but I didn't add any based on your comment


class TypeOneTests(BaseTest):
    def setUp(self):
        super(TypeOneTests, self).setUp()
        print "TypeOneTests setUp"

    def tearDown(self):
        print "TypeOneTests tearDown"

    def test(self):
        print "a test in TypeOneTests"


class TypeTwoTests(BaseTest):
    def setUp(self):
        super(TypeTwoTests, self).setUp()
        print "TypeTwoTests additional setUp"

    def tearDown(self):
        print "TypeTwoTests tearDown"
        super(TypeTwoTests, self).tearDown()

    def test(self):
        print "a test in TypeTwoTests"


if __name__ == "__main__":
    unittest.main()

Output:

BaseTest setUp
TypeOneTests setUp
a test in TypeOneTests
TypeOneTests tearDown
.BaseTest setUp
TypeTwoTests additional setUp
a test in TypeTwoTests
TypeTwoTests tearDown
BaseTest tearDown
.
----------------------------------------------------------------------
Ran 2 tests in 0.002s

OK

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM