Ada*_*ith 29 python python-2.7 python-unittest
我有一个包含目录"tests"的包,我正在存储我的单元测试.我的包看起来像:
.
??? LICENSE
??? models
? ??? __init__.py
??? README.md
??? requirements.txt
??? tc.py
??? tests
? ??? db
? ? ??? test_employee.py
? ??? test_tc.py
??? todo.txt
Run Code Online (Sandbox Code Playgroud)
从我的包目录,我希望能够找到tests/test_tc.py和tests/db/test_employee.py.我不想安装第三方库(nose或其他),或者必须手动构建一个TestSuite以运行它.
当然有一种方法可以告诉unittest discover他们一旦发现测试就不要停止寻找?python -m unittest discover -s tests会发现tests/test_tc.py并python -m unittest discover -s tests/db会找到tests/db/test_employee.py.有没有找到两者的方法?
Ada*_*ith 62
在进行一些挖掘时,似乎只要更深层次的模块仍可导入,它们就会被发现python -m unittest discover.然后,解决方案只是将__init__.py文件添加到每个目录以使其成为包.
.
??? LICENSE
??? models
? ??? __init__.py
??? README.md
??? requirements.txt
??? tc.py
??? tests
? ??? db
? ? ??? __init__.py # NEW
? ? ??? test_employee.py
? ??? __init__.py # NEW
? ??? test_tc.py
??? todo.txt
Run Code Online (Sandbox Code Playgroud)
只要每个目录都有一个__init__.py,python -m unittest discover就可以导入相关test_*模块.
如果您可以__init__.py在测试中添加文件,则可以在其中放置一个可以load_tests为您处理发现的函数.
如果测试包名称(带有目录
__init__.py)与模式匹配,则将检查包的"load_tests"函数.如果存在,那么将使用loader,tests,pattern调用它.如果load_tests存在,那么发现操作 不递归到包装,load_tests负责加载所有测试包.
我很不相信这是最好的方法,但编写该功能的一种方法是:
import os
import pkgutil
import inspect
import unittest
# Add *all* subdirectories to this module's path
__path__ = [x[0] for x in os.walk(os.path.dirname(__file__))]
def load_tests(loader, suite, pattern):
for imp, modname, _ in pkgutil.walk_packages(__path__):
mod = imp.find_module(modname).load_module(modname)
for memname, memobj in inspect.getmembers(mod):
if inspect.isclass(memobj):
if issubclass(memobj, unittest.TestCase):
print("Found TestCase: {}".format(memobj))
for test in loader.loadTestsFromTestCase(memobj):
print(" Found Test: {}".format(test))
suite.addTest(test)
print("=" * 70)
return suite
Run Code Online (Sandbox Code Playgroud)
非常难看,我同意.
首先,将所有子目录添加到测试包的路径(Docs).
然后,您使用pkgutil走路径,寻找包或模块.
当它找到一个时,它会检查模块成员以查看它们是否是类,如果它们是类,它们是否是它们的子类unittest.TestCase.如果是,则将类内的测试加载到测试套件中.
现在,从项目根目录中,您可以输入
python -m unittest discover -p tests
Run Code Online (Sandbox Code Playgroud)
使用-p模式开关.如果一切顺利,你会看到我所看到的,这是:
Found TestCase: <class 'test_tc.TestCase'>
Found Test: testBar (test_tc.TestCase)
Found Test: testFoo (test_tc.TestCase)
Found TestCase: <class 'test_employee.TestCase'>
Found Test: testBar (test_employee.TestCase)
Found Test: testFoo (test_employee.TestCase)
======================================================================
....
----------------------------------------------------------------------
Ran 4 tests in 0.001s
OK
Run Code Online (Sandbox Code Playgroud)
这是什么预期,我的每一个两个示例文件包含了两个测试,testFoo和testBar每一个.
编辑:经过一些挖掘后,看起来您可以将此功能指定为:
def load_tests(loader, suite, pattern):
for imp, modname, _ in pkgutil.walk_packages(__path__):
mod = imp.find_module(modname).load_module(modname)
for test in loader.loadTestsFromModule(mod):
print("Found Tests: {}".format(test._tests))
suite.addTests(test)
Run Code Online (Sandbox Code Playgroud)
这使用loader.loadTestsFromModule()方法而不是loader.loadTestsFromTestCase()我上面使用的方法.它仍然修改了tests包路径并走向它寻找模块,我认为这是关键.
现在输出看起来有点不同,因为我们一次在主要测试套件中添加一个找到的测试套件suite:
python -m unittest discover -p tests
Found Tests: [<test_tc.TestCase testMethod=testBar>, <test_tc.TestCase testMethod=testFoo>]
Found Tests: [<test_employee.TestCase testMethod=testBar>, <test_employee.TestCase testMethod=testFoo>]
======================================================================
....
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
Run Code Online (Sandbox Code Playgroud)
但是我们仍然可以在两个子目录中获得我们预期的4个测试.
| 归档时间: |
|
| 查看次数: |
12667 次 |
| 最近记录: |