查找每个可能的测试用例的输入

Finding inputs of every possible test case

假设我有一个 Python 程序,它接受大约 40 个用户输入和 returns 对他们寿命的预测。用户输入主要是分类或有限的,例如性别、吸烟状况和出生年份。

我想通过测试每个字段的所有可接受值来最大化我的测试用例,例如 sex:['Male', 'Female', None]。有没有不使用数十个嵌套 for 循环的好方法?例如,itertools 函数。我正在考虑像 scikit-learn 的网格搜索这样的东西,你可以在其中列出可接受的值,并通过检查所有可能的组合来启动超参数优化

我想避免:

for sex in ['male', 'female', None]:
    for smoking_status in ['smoker', 'non-smoker', None]:
        for birth_year in [1900, ..., 2022, None]:
           assert(myfunc(sex, smoking_status, birth_year) == trueOutput)

假设 trueOutput 是动态的并且总是给出正确的值(我计划将 Python 输出交叉引用到 Excel 电子表格并重写 Excel 输入每个测试用例都得到更新的输出)。我还计划将每个可能的测试用例写入代表特定用户数据的 JSON 文件,这样我就可以测试失败的用例

您想像这样使用 itertools.product

sex = ['m', 'f', None]
smoking = ['smoker', 'non-smoker', None]
birth = [1999, 2000, 2001, None]

for item in itertools.product(sex, smoking, birth):
    print(item)

要将参数传递给您的函数,请使用扩展运算符:

sex = ['m', 'f', None]
smoking = ['smoker', 'non-smoker', None]
birth = [1999, 2000, 2001, None]

for item in itertools.product(sex, smoking, birth):
     assert myfunc(*item) == trueOutput
# or
for se, sm, b in itertools.product(sex, smoking, birth):
     assert myfunc(se, sm, b) == trueOutput

itertools.product() 正是您想要的,但要获得其他功能,请将每个选择收集到字典中

category_inputs_mapping = {
    "gender":     ("male", "female", ..., None),
    "birth_year": sorted(2022 - x for x in range(150)),
    ...
}

然后创建一个函数,为您生成每种可能性

def gen_inputs_mapper(d: Dict):
    # opportunity to inspect dict
    for values in itertools.product(*d.values()):
        # opportunity to assert/inspect values
        yield {k: v for k, v in zip(d.keys(), values)}

最后,依次获取每种可能性及其索引

for index, possibility in enumerate(gen_inputs_mapper(category_inputs_mapping)):
    result = myfunc(**possibility)      # unpack dict to args
    assert result = true_output[index]  # nth index from computed sheet