Pyunit源码笔记之三 创建testsuit/testcase

来源:互联网 发布:龙门式加工中心编程 编辑:程序博客网 时间:2024/06/08 18:41

关于self.parseArgs(argv)之createTests()

argv的值是['D:\\hy\\ws\\Prj_jd\\pkg_jd\\utamy.py'],  self.testNames目前还是None, 主要关注下面的self.createTests()

    def parseArgs(self, argv):        ......        ......        else:            self.testNames = list(self.defaultTest)        self.createTests()
self.testNames是None, 调用self.test = self.testLoader.loadTestsFromModule(self.module)

def createTests(self):        if self.testNames is None:            self.test = self.testLoader.loadTestsFromModule(self.module)        else:            self.test = self.testLoader.loadTestsFromNames(self.testNames,                                                           self.module)

在loader.py里面的loadTestsFromModule: 由于 issubclass(obj, case.TestCase)判断,所以obj只有<class '__main__.MyTest'>,

def loadTestsFromModule(self, module, *args, pattern=None, **kws):        .......        tests = []        for name in dir(module):            obj = getattr(module, name)                     if isinstance(obj, type) and issubclass(obj, case.TestCase):                print("obj:{}".format(obj))                tests.append(self.loadTestsFromTestCase(obj))        load_tests = getattr(module, 'load_tests', None)        tests = self.suiteClass(tests)        if load_tests is not None:            try:                return load_tests(self, tests, pattern)            except Exception as e:                error_case, error_message = _make_failed_load_tests(                    module.__name__, e, self.suiteClass)                self.errors.append(error_message)                return error_case        return tests
在下面的self.loadTestsFromTestCase(obj)中:  先看getTestCaseNames

 runTest 这个可以作为单独的测试用例,后面可能会讲到

def loadTestsFromTestCase(self, testCaseClass):        """Return a suite of all tests cases contained in testCaseClass"""        if issubclass(testCaseClass, suite.TestSuite):            raise TypeError("Test cases should not be derived from "                            "TestSuite. Maybe you meant to derive from "                            "TestCase?")        testCaseNames = self.getTestCaseNames(testCaseClass)        if not testCaseNames and hasattr(testCaseClass, 'runTest'):            testCaseNames = ['runTest']        loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))        return loaded_suite

在下面的getTestCaseNames(self, testCaseClass)中: testCaseClass 是<class '__main__.MyTest'>

这里prefix=self.testMethodPrefix= 'test',

    def getTestCaseNames(self, testCaseClass):        """Return a sorted sequence of method names found within testCaseClass        """        def isTestMethod(attrname, testCaseClass=testCaseClass,                         prefix=self.testMethodPrefix):            return attrname.startswith(prefix) and \                callable(getattr(testCaseClass, attrname))        testFnNames = list(filter(isTestMethod, dir(testCaseClass)))        if self.sortTestMethodsUsing:            testFnNames.sort(key=functools.cmp_to_key(self.sortTestMethodsUsing))        return testFnNames

dir(testCaseClass)包括了测试用例类<class '__main__.MyTest'>的module,里面很多东西:注意最后面几个,

['__call__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_addExpectedFailure', '_addSkip', '_addUnexpectedSuccess', '_baseAssertEqual', '_classSetupFailed', '_deprecate', '_diffThreshold', '_feedErrorsToResult', '_formatMessage', '_getAssertEqualityFunc', '_truncateMessage', 'addCleanup', 'addTypeEqualityFunc', 'assertAlmostEqual', 'assertAlmostEquals', 'assertCountEqual', 'assertDictContainsSubset', 'assertDictEqual', 'assertEqual', 'assertEquals', 'assertFalse', 'assertGreater', 'assertGreaterEqual', 'assertIn', 'assertIs', 'assertIsInstance', 'assertIsNone', 'assertIsNot', 'assertIsNotNone', 'assertLess', 'assertLessEqual', 'assertListEqual', 'assertLogs', 'assertMultiLineEqual', 'assertNotAlmostEqual', 'assertNotAlmostEquals', 'assertNotEqual', 'assertNotEquals', 'assertNotIn', 'assertNotIsInstance', 'assertNotRegex', 'assertNotRegexpMatches', 'assertRaises', 'assertRaisesRegex', 'assertRaisesRegexp', 'assertRegex', 'assertRegexpMatches', 'assertSequenceEqual', 'assertSetEqual', 'assertTrue', 'assertTupleEqual', 'assertWarns', 'assertWarnsRegex', 'assert_', 'countTestCases', 'debug', 'defaultTestResult', 'doCleanups', 'fail', 'failIf', 'failIfAlmostEqual', 'failIfEqual', 'failUnless', 'failUnlessAlmostEqual', 'failUnlessEqual', 'failUnlessRaises', 'failureException', 'id', 'longMessage', 'maxDiff', 'run', 'setUp', 'setUpClass', 'shortDescription', 'skipTest', 'subTest', 'tearDown', 'tearDownClass', 'testmul', 'testsum']

这里筛选出的testFnNames是['testmul', 'testsum']。


回到上面的loadTestsFromTestCase()返回的loaded_suite:

<unittest.suite.TestSuite tests=[<__main__.MyTest testMethod=testmul>, <__main__.MyTest testMethod=testsum>]

回到上面的loadTestsFromModule(),把suite追加到tests列表中,然后把tests也转化为suite, tests的列表

<unittest.suite.TestSuite tests=[<unittest.suite.TestSuite tests=[<__main__.MyTest testMethod=testmul>, <__main__.MyTest testMethod=testsum>]>]>