简体   繁体   中英

Python unit tests run function after all test

I need to test smth on python via ssh. I don't want to make ssh connection for every test, because it is to long, I have written this:

class TestCase(unittest.TestCase):
    client = None
    def setUp(self):
        if not hasattr(self.__class__, 'client') or self.__class__.client is None:
            self.__class__.client = paramiko.SSHClient()
            self.__class__.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            self.__class__.client.connect(hostname=consts.get_host(), port=consts.get_port(), username=consts.get_user(),
                                password=consts.get_password())

    def test_a(self):
        pass

    def test_b(self):
        pass

    def test_c(self):
        pass

    def disconnect(self):
        self.__class__.client.close()

and my runner

if __name__ == '__main__':
    suite = unittest.TestSuite((
        unittest.makeSuite(TestCase),
    ))
    result = unittest.TextTestRunner().run(suite)
    TestCase.disconnect()
    sys.exit(not result.wasSuccessful())

In this version I get error TypeError: unbound method disconnect() must be called with TestCase instance as first argument (got nothing instead) . So how i can call disconnect after all tests pass? With best regards.

You should use setUpClass and tearDownClass instead, if you want to keep the same connection for all tests. You'll also need to make the disconnect method static, so it belongs to the class and not an instance of the class.

class TestCase(unittest.TestCase):

     def setUpClass(cls):
         cls.connection = <your connection setup>

     @staticmethod
     def disconnect():
         ... disconnect TestCase.connection

     def tearDownClass(cls):
         cls.disconnect()

you can do it by defining startTestRun , stopTestRun of unittest.TestResult class. setUpClass and tearDownClass are running per test class(per test file) so if you have multiple files this methods will run for each one.

by adding following code to my tests/__init__.py i managed to achieve it. this code runs only once for all tests(regardless of number of test classes and test files).

def startTestRun(self):
    """
    https://docs.python.org/3/library/unittest.html#unittest.TestResult.startTestRun
    Called once before any tests are executed.

    :return:
    """
    DockerCompose().start()


setattr(unittest.TestResult, 'startTestRun', startTestRun)


def stopTestRun(self):
    """
    https://docs.python.org/3/library/unittest.html#unittest.TestResult.stopTestRun
    Called once after all tests are executed.

    :return:
    """
    DockerCompose().compose.stop()


setattr(unittest.TestResult, 'stopTestRun', stopTestRun)

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