Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用pytest为实例方法编写单元测试的正确方法_Python_Unit Testing_Testing_Pytest - Fatal编程技术网

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文件并创建不同的类实例(如您所说,在“对象级别”上进行测试)是进行集成测试的第一步。最后一点我可能错了,但希望有人能在这一点或其他点上改进我的答案:)