#!/usr/bin/env python
import unittest
import inspect
import sys
import re
class Foo(unittest.TestCase):
@staticmethod
def test_baz():
pass
@classmethod
def test_mu(cls):
pass
def test_foo(self):
self.assertEqual('foo', 'foo')
def bar_test(self):
self.assertEqual('bar', 'bar')
class Bar:
pass
if __name__ == '__main__':
runner = unittest.TextTestRunner(verbosity=2)
tests = []
is_member_valid_test_class = lambda member: inspect.isclass(member) and \
issubclass(member, unittest.TestCase)
for module_name, module_obj in sys.modules.items():
if not re.match(r'unittest', module_name):
for cls_name, cls in inspect.getmembers(
module_obj, is_member_valid_test_class):
for methname, methobj in cls.__dict__.items():
if inspect.isroutine(methobj) and re.match(r'test', methname):
tests.append(cls(methname))
suite = unittest.TestSuite(tests=tuple(tests))
runner.run(suite)
结果是:
test_foo (__main__.Foo) ... ok
test_baz (__main__.Foo) ... ok
test_mu (__main__.Foo) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.001s
OK
import random
import unittest
class TestSequenceFunctions(unittest.TestCase):
def setUp(self):
self.seq = range(10)
def test_shuffle(self):
# make sure the shuffled sequence does not lose any elements
random.shuffle(self.seq)
self.seq.sort()
self.assertEqual(self.seq, range(10))
# should raise an exception for an immutable sequence
self.assertRaises(TypeError, random.shuffle, (1,2,3))
def test_choice(self):
element = random.choice(self.seq)
self.assertTrue(element in self.seq)
def test_sample(self):
with self.assertRaises(ValueError):
random.sample(self.seq, 20)
for element in random.sample(self.seq, 5):
self.assertTrue(element in self.seq)
if __name__ == '__main__':
unittest.main()
A testcase is created by subclassing unittest.TestCase. The three
individual tests are defined with methods whose names start with the
letters test. This naming convention informs the test runner about
which methods represent tests.
for name in dir(module):
obj = getattr(module, name)
if isinstance(obj, type) and issubclass(obj, case.TestCase):
tests.append(self.loadTestsFromTestCase(obj))
我编写了一些代码,试图在下面执行与unittest.main()类似的操作。总之,我遍历模块,对于不以“unittest”名称开头的模块,我检查其成员。如果这些成员是一个类,并且是unittest.TestCase的子类,那么我将解析该类的成员。然后,如果这些类成员是以“test”开头的函数或方法,则将其添加到测试列表中。类对象的
__dict__
用于内省方法/函数,因为使用inspect.getmembers可能会显示太多。最后,这个测试列表被转换成一个元组并打包成一个套件。然后使用运行程序在详细级别2运行该套件。请注意,当然,如果您不需要此限制,可以删除在函数/方法名开头检查“test”的正则表达式,以便将bar_test()包含到测试列表中。结果是:
“main”函数搜索导入模块中继承unittest.TestCase的所有类。和当前路径,然后尝试运行以“test”开头的每个方法
来自python's document:
所以我在我的
Python27/Lib
目录中四处寻找。。。unittest.main
实际上是类unittest.TestProgram
的别名。因此,所发生的是构造一个这个实例,它的__init__
运行,这将执行一系列健全性检查和配置,包括从中调用它的模块的动态导入(它使用__import__
函数,默认情况下,__main__
是要导入的模块的名称)。所以现在它有一个self.module
属性,它包含一个表示源代码的模块对象。最终,它得到了以下代码:
其中
self.testLoader
是unittest.TestLoader
的实例。这种方法包括:因此,它使用module对象的
dir
来获取您定义的所有全局变量(包括类)的名称,过滤来自unittest.TestCase
的类(在本地,case.TestCase
是该类的别名),然后在这些类中查找要添加到tests
列表中的测试方法。搜索的行为类似:因此,它使用类的
dir
来获取要尝试的名称列表,查找具有这些名称的属性,并选择那些以self.testMethodPrefix
(默认情况下为'test'
)开头且可调用(依次具有__call__
属性)的属性。(实际上,我很惊讶他们没有在这里使用内置的callable
函数。我想这是为了避免获取嵌套类。)相关问题 更多 >
编程相关推荐