Python 使用pytest为实例方法编写单元测试的正确方法
我想用几种数据转换方法为类编写单元测试 高级别:Python 使用pytest为实例方法编写单元测试的正确方法,python,unit-testing,testing,pytest,Python,Unit Testing,Testing,Pytest,我想用几种数据转换方法为类编写单元测试 高级别: 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"] de
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\u class.transform\u data()
。
它将dict作为输入,将其作为数据帧读取,并进行一些转换
据我所知,我需要几个固定装置d1
,d2
,d3
。。。(作为数据的不同值,表示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\u data
中的转换也取决于属性self.value2
,如何在不创建实例的情况下为value2
传递不同的值
我的班级的李>
一般来说,我也不完全清楚是在“对象”级别还是在“方法”级别进行测试。在上面,我描述了一种“方法”——方法
(因为我主要对transform\u data
的结果感兴趣)。另一种方法是提供不同的.yml文件,从而创建
myu类的不同测试实例
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\u class.transform\u data()
的函数输入,它并不(直接)依赖于yml1
的内容,而是依赖于my\u class.get\u data()
的响应,这似乎没有什么意义。如何测试数据的不同输入值
在这种情况下,编写单元测试的正确方法是什么?我根本不是专家,但我发现您的问题很有趣,因此我将尝试发布一个既仔细又有建设性的答案:
您验证transform\u data
在输入和输出对方面的行为是否符合预期的方法对我来说似乎是有效的。单元测试验证源代码中最小的组件(“单元”)的行为是否符合预期,我想说的是,三种方法的行为差异足以使这些方法成为单元
如果您不确定是在测试文件内还是在外部.pkl文件中声明输入字典对和预期输出,我猜这些输入/输出对是大(大小)还是多(数量):
- 在第一种情况下,您可以将一个默认的
data\u dict
输入字典和一个默认的预期输出声明为两个fixture,稍后您可以在测试函数中使用它们。您可以使用与data\u dict
字典中的元素相对应的不同值对测试函数进行参数化,然后使用这些参数化值
- 在第二种情况下,我认为最好将测试用例的数量减少到几个相关的,并尝试将它们的输入/输出规范保存在测试文件中
通过(再次)对my_class
实例的value2
属性进行monkeypatch,可以为value2
传递不同的值。但是,您需要至少声明一次这样的实例(在函数内部或外部)
就像我在上面写的一样,在“方法级别”而不是“对象级别”上进行测试对我来说似乎对面向对象软件也是有效的。在我看来,提供不同的.yml文件并创建不同的类实例(如您所说,在“对象级别”上进行测试)是进行集成测试的第一步。最后一点我可能错了,但希望有人能在这一点或其他点上改进我的答案:)