我的单元测试很复杂,并且根据具体情况手动对其进行编程并不容易(或不可能)。有益的是能够动态添加测试数据,并且为了可读性,为每个数据拥有自己的测试方法,最好是通过动态生成测试方法。
这是一个(非工作)示例:
class TestParam(unittest.TestCase):
def __init__(self, _):
dir = 'test_param_items'
for f in os.listdir(dir):
if os.path.isfile(dir + "\\" + f) and f[0] != '_':
print f
func = self.TestCaseFactory(f, dir)
setattr(TestParam, func.__name__, func)
super(TestParam, self).__init__(func.__name__)
def TestCaseFactory(self, inFileName, inDir):
def func(inObj):
print inFileName
with open(inDir + "\\" + inFileName, "r") as testFile:
testNode = testFile.read()
par = Param(inETree=etree.XML(testNode))
self.assertEqual(testNode, etree.tostring(par.eTree))
func.__name__ = "test_" + inFileName[:-4]
return func
这里的测试文件是普通的 XML。 但是Python 2.7的测试运行器从类而不是实例中获取测试方法,并通过实例运行它们:
loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
所以我无法运行生成的测试函数。 我的错误显然是,通常一个测试方法会涵盖许多测试用例,但我认为编写 10 到 100 个这样的方法非常耗时。如果每个方法都有一堆测试用例,并且测试(方法)无法使用大量数据搜索实际的 AssertEquals 方法输出,这对我来说会非常困惑。 我会找到一种方法
def testMethod1(self):
load('testFile1')
def testMethod2(self):
load('testFile2')
等等。相当多的解体(测试数据和测试方法被分成不同的文件)。
对此有什么想法吗?我的做法有错吗?有可能实现吗?
对这种方法有什么想法吗?
最佳答案
最后我通过调用 TestSuites 完全基于 Python 2.7 的基础设施解决了这个问题:
#modules of the tested objects not included here
from TemplateMaker import Param
from lxml import etree
#/
import unittest
import os
import os.path
class TestSuiteParam(unittest.TestSuite):
def __init__(self):
self._tests = []
dir = 'test_param_items'
for f in os.listdir(dir):
if os.path.isfile(dir + "\\" + f) and f[0] != '_':
# "_test_filename" is for inactive/switched off tests
tp = TestParam(f, dir)
self.addTest(tp)
super(TestSuiteParam, self).__init__(self._tests)
class TestParam(unittest.TestCase):
def __init__(self, inFile, inDir):
func = self.TestCaseFactory(inFile, inDir)
setattr(TestParam, func.__name__, func)
super(TestParam, self).__init__(func.__name__)
@staticmethod
def TestCaseFactory(inFileName, inDir):
def func(inObj):
with open(inDir + "\\" + inFileName, "r") as testFile:
testNode = testFile.read()
par = Param(inETree=etree.XML(testNode))
inObj.assertEqual(testNode, etree.tostring(par.eTree))
func.__name__ = "test_" + inFileName[:-4]
return func
请注意,此解决方案仍然不完美(由于某种原因,TestCase 实例只能有一种测试方法,因为其父级的 init() 只处理一个),但可以工作。
关于Python单元测试: adding test methods dynamically?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53770170/