如果您感兴趣,问题在前,解释在后。
在py.test上下文中,如何从少量的测试函数模板生成大量的测试函数?
类似于:
models = [model1,model2,model3]
data_sets = [data1,data2,data3]
def generate_test_learn_parameter_function(model,data):
def this_test(model,data):
param = model.learn_parameters(data)
assert((param - model.param) < 0.1 )
return this_test
for model,data in zip(models,data_sets):
# how can py.test can see the results of this function?
generate_test_learn_parameter_function(model,data)
解释:
我编写的代码需要一个模型结构,一些数据,并学习模型的参数。因此,我的单元测试包括一堆模型结构和预生成的数据集,然后是每个结构+数据上完成的大约5个机器学习任务。
因此,如果我手动编码,我需要每个模型每个任务一个测试。每次我想出一个新模型时,我需要复制并粘贴这5个任务,更改我指向的pickled结构+数据。这让我觉得很不好。理想情况下,我希望有5个模板函数来定义我的5个任务,然后只需为我指定的结构列表输出测试函数。
搜索引擎告诉我可以使用a)工厂或b)闭包来解决这个问题,但两者都让我感到困惑,并认为一定有更简单的方法,因为这个问题必须经常面对真正的程序员。那么有没有呢?
编辑:以下是如何解决此问题!
def pytest_generate_tests(metafunc):
if "model" in metafunc.funcargnames:
models = [model1,model2,model3]
for model in models:
metafunc.addcall(funcargs=dict(model=model))
def test_awesome(model):
assert model == "awesome"
这将对我清单中的每个模型应用“test_awesome”测试!感谢 @dfichter!(注意:顺便说一句,那个assert语句总是通过的)
def test_learn:
这样的测试代码,对于每个模型都是for model in models: assert(error < threshold)
。但这意味着测试可能会在任何一个模型上失败,而我希望有一个测试用例只对一个模型失败,并且另一个相同的机器学习函数的测试用例能够通过。 - Mike Dewar