使用python和unittest我有测试目录的结构:
tests/
__init__.py
test_001.py
data/
data_001_in.py
data_001_out.py
,其中
data_001_in.py
:要在测试函数中使用的输入数据data_001_out.py
:从测试函数预期的输出数据我在python词典中有输入和输出,因为它比使用json,sqlite等更容易。
我尝试使用一组具有相同格式的输入/输出数据,并对每对数据应用测试:
tests/
__init__.py
test_001.py
data/
data_001_in.py
data_001_out.py
data_002_in.py
data_002_out.py
data_003_in.py
data_003_out.py
是否有任何方法/方法可以使此任务更容易?
答案 0 :(得分:0)
在问题nose, unittest.TestCase and metaclass: auto-generated test_* methods not discovered中被启发,我用一个元类解决了。首先,我将目录数据结构更改为
├── data
│ ├── __init__.py
│ ├── data001
│ │ ├── __init__.py
│ │ ├── datain.py
│ │ ├── dataout.py
│ └── data002
│ ├── __init__.py
│ ├── datain.py
│ ├── dataout.py
└── metatest.py
其次,我使用子目录和基本测试中的数据创建了一个用于创建新测试的元类。
import unittest
import os
import copy
def data_dir():
return os.path.join(os.path.dirname(__file__), 'data')
def get_subdirs(dir_name):
""" retorna subdirectorios con path completo"""
subdirs = []
for f in os.listdir(dir_name):
f_path = os.path.join(dir_name, f)
if os.path.isdir(f_path):
subdirs.append(f)
return subdirs
def get_data_subdirs():
return get_subdirs(data_dir())
def data_py_load(file_name):
""" carga diccionario data desde archivo .py """
name = file_name.split('.py')[0]
path_name = 'data.' + name
exec_str = "from {} import *".format(path_name)
exec(exec_str)
return data
class TestDirectories(type):
def __new__(cls, name, bases, attrs):
subdirs = get_data_subdirs()
callables = dict([
(meth_name, meth) for (meth_name, meth) in attrs.items() if
meth_name.startswith('_test')
])
data = {}
for d in subdirs:
data[d] = {}
data[d]['name'] = d
out_path = "{}.dataout.py".format(d)
data[d]['out'] = data_py_load(out_path)
var_path = "{}.datain.py".format(d)
data[d]['in'] = data_py_load(var_path)
for meth_name, meth in callables.items():
for d in subdirs:
new_meth_name = meth_name[1:]
# name of test to add, _test to test
test_name = "{}_{}".format(new_meth_name, d)
# deep copy for dictionaries
testeable = lambda self, func=meth, args=copy.deepcopy(data[d]): func(self, args)
attrs[test_name] = testeable
return type.__new__(cls, name, bases, attrs)
class TestData(unittest.TestCase):
__metaclass__ = TestDirectories
def _test_name(self, data):
in_name = data['in']['name']
out_name = data['out']['name']
print in_name, out_name
self.assertEquals(in_name, out_name)
if __name__ == '__main__':
unittest.main(verbosity=2)
而且,当我跑步时
$ python metatest.py
test_name_data001 (__main__.TestData) ... Alice Alice
ok
test_name_data002 (__main__.TestData) ... Bob Bob
ok
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK