Can Python's unittest test in parallel, like nose can?

后端 未结 7 1148
小蘑菇
小蘑菇 2020-12-01 01:53

Python\'s NOSE testing framework has the concept of running multiple tests in parallel.

The purpose of this is not to test concurrency in the code, but to make test

7条回答
  •  我在风中等你
    2020-12-01 02:39

    You can override the unittest.TestSuite and implement some concurrency paradigm. Then, you use your customized TestSuite class just like normal unittest. In the following example, I implement my customized TestSuite class using async:

    import unittest
    import asyncio
    
    class CustomTestSuite(unittest.TestSuite):
        def run(self, result, debug=False):
            """
            We override the 'run' routine to support the execution of unittest in parallel
            :param result:
            :param debug:
            :return:
            """
            topLevel = False
            if getattr(result, '_testRunEntered', False) is False:
                result._testRunEntered = topLevel = True
            asyncMethod = []
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            for index, test in enumerate(self):
                asyncMethod.append(self.startRunCase(index, test, result))
            if asyncMethod:
                loop.run_until_complete(asyncio.wait(asyncMethod))
            loop.close()
            if topLevel:
                self._tearDownPreviousClass(None, result)
                self._handleModuleTearDown(result)
                result._testRunEntered = False
            return result
    
        async def startRunCase(self, index, test, result):
            def _isnotsuite(test):
                "A crude way to tell apart testcases and suites with duck-typing"
                try:
                    iter(test)
                except TypeError:
                    return True
                return False
    
            loop = asyncio.get_event_loop()
            if result.shouldStop:
                return False
    
            if _isnotsuite(test):
                self._tearDownPreviousClass(test, result)
                self._handleModuleFixture(test, result)
                self._handleClassSetUp(test, result)
                result._previousTestClass = test.__class__
    
                if (getattr(test.__class__, '_classSetupFailed', False) or
                        getattr(result, '_moduleSetUpFailed', False)):
                    return True
    
            await loop.run_in_executor(None, test, result)
    
            if self._cleanup:
                self._removeTestAtIndex(index)
    
    class TestStringMethods(unittest.TestCase):
    
        def test_upper(self):
            self.assertEqual('foo'.upper(), 'FOO')
    
    
        def test_isupper(self):
            self.assertTrue('FOO'.isupper())
            self.assertFalse('Foo'.isupper())
    
    
        def test_split(self):
            s = 'hello world'
            self.assertEqual(s.split(), ['hello', 'world'])
            # check that s.split fails when the separator is not a string
            with self.assertRaises(TypeError):
                s.split(2)
    
    
    if __name__ == '__main__':
        suite = CustomTestSuite()
        suite.addTest(TestStringMethods('test_upper'))
        suite.addTest(TestStringMethods('test_isupper'))
        suite.addTest(TestStringMethods('test_split'))
        unittest.TextTestRunner(verbosity=2).run(suite)
    

    In the main, I just construct my customized TestSuite class CustomTestSuite, add all the test cases, and finally run it.

提交回复
热议问题