我想为类写单元测试,有几种数据转换的方法。
高层次的。
class my_class:
def __init__(self, file):
# read data out of .yml config file
config = read_data_from_yml_config(file)
self.value1 = config["value1"]
self.value2 = config["value2"]
def get_and_transform(self):
data_dict = self.get_data()
transformed_data = self.transform_data(data_dict)
return transformed_data
def get_data(self):
data_dict = request_based_on_value1(self.value1)
return data_dict
def transform_data(self, data_dict):
trnsf = transform1(data_dict, self.value2)
return trnsf
在这里,我有几个问题。这里主要测试的是 my_class.transform_data()
. 它把一个dict作为输入,把它读成一个pandas数据框架并做一些转换。
在我的理解中,我需要几个夹具 d1
, d2
, d3
,...(因为对 data_dict
),它们代表my_class.transform_data()的不同测试用例输入。由于我想确保输出结果与预期一致,我将定义我的预期输出。
o1 # expected output for transform_data(d1)
o2, o3, ... # respectively
我有几个问题
d1
, d2
, ... 和 o1
, o2
,....? 我要么在 test_my_class.py
-文件或将 d1_sample.pkl, ... 存储在 tests/
文件夹.在这里,我会选择一个最小的例子,为两个 d
和 o
transform_data
也取决于属性 self.value2
,我如何传递不同的值给 value2
的实例而不创建 my_class
? 总的来说,我也不太清楚我是在 "对象 "层面还是在 "方法 "层面进行测试。在上面,我描述了一个 "方法 "的方法(因为我主要对以下结果感兴趣 transform_data
). 另一种方法是提供不同的.yml文件,从而创建不同的测试实例的 my_class
.
def yml1():
config = read_in_yml1()
return config
# and so on for different configurations.
然后进行测试。
@pytest.mark.parametrize("test_input, expected", [(yml1, ???), (yml2, ???)])
def test_my_class():
test_class = my_class(file)
assert test_class.transform_data == expected
然而,作为函数输入 my_class.transform_data()
并不(直接)取决于内容。yml1
而不是反应。my_class.get_data()
,这似乎没什么意义。我如何测试不同输入值的 data_dict
?
在这种情况下,正确的编写单元测试的方法是什么?
我不是什么专家,但我觉得你的问题很有趣,所以我打算试着发一个既仔细又有建设性的答案。
transform_data
在我看来,对输入和输出对的行为符合预期是有效的。单元测试验证了你的源代码中最小的组件("单元")的行为是否符合预期,我想说的是,你的三个方法的行为是不同的,足以让这些方法成为单元。data_dict
输入字典和一个默认的预期输出作为两个固定装置,您可以在以后的时候 猴皮 内的测试函数。你可以用不同的值来设定测试函数的参数,这些值对应于 data_dict
词典,然后 monkeypatch的默认元素 data_dict
灯具 与这些参数化的值。value2
猴子补丁的 value2
的实例的属性。my_class
. 然而,你需要至少声明一次这样的实例(无论是在你的函数内部还是外部)。就像我上面写的那样,在 "方法级 "而不是 "对象级 "上进行测试对我来说也是面向对象的软件。提供不同的.yml文件并创建不同的类实例(所以像你说的那样在 "对象级 "上进行测试)在我看来,这是做测试的第一步。融合 测试。最后一点我可能错了,但希望有人能改进我在这一点或其他方面的回答:)。