Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.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 如何测试应该与不同类的其他对象混合在一起的列表中的对象的字段值?_Python_Pytest - Fatal编程技术网

Python 如何测试应该与不同类的其他对象混合在一起的列表中的对象的字段值?

Python 如何测试应该与不同类的其他对象混合在一起的列表中的对象的字段值?,python,pytest,Python,Pytest,我正在使用pytest并尝试检查对象的某个字段中是否有正确的内容。我面临的问题是,对象出现在一个列表中,它可以位于任何位置,并与来自不同类的对象混合,而该字段甚至不存在 下面是一个测试我需要什么的例子。该示例按其应有的方式工作,但我认为这不是一个很好的解决方案,因为它在测试中测试了2个条件(列表中的实例和正确的内容,如果它找到了实例),并且还因为必须中断测试函数看起来不是很干净 有没有人建议用一种更优雅、更正确的方法来测试这一点 import pytest class Foo: def

我正在使用pytest并尝试检查对象的某个字段中是否有正确的内容。我面临的问题是,对象出现在一个列表中,它可以位于任何位置,并与来自不同类的对象混合,而该字段甚至不存在

下面是一个测试我需要什么的例子。该示例按其应有的方式工作,但我认为这不是一个很好的解决方案,因为它在测试中测试了2个条件(列表中的实例和正确的内容,如果它找到了实例),并且还因为必须中断测试函数看起来不是很干净

有没有人建议用一种更优雅、更正确的方法来测试这一点

import pytest

class Foo:
    def __init__(self,name):
        self.name = name

class Bar:
    pass

def test_instance_in_list():

    l = [Bar(), Foo('foo'), Bar()]                      # Will pass the test
#    l = [Bar(), Bar(), Bar()]                     # Will NOT pass the test - "No instance"
#    l = [Bar(), Foo('other name'), Bar()]     # Will NOT pass the test - "Assertion fail"

    for item in l:
        if isinstance(item,Foo):
            assert item.name == 'foo'
            return
    pytest.fail("There wasn't a Foo instance in the list")
在三种条件下运行测试的预期输出为:

使用l=[Bar(),Foo('Foo'),Bar()]运行的结果

使用l=[Bar(),Bar(),Bar()]运行的结果

使用l=[Bar(),Foo('other name'),Bar()]运行的结果


感谢您的建议和帮助,以找到更好的方式获得相同的结果:-)

如果您不想在同一测试中检查实例的可用性,这可能是其他方法之一

def get_params():
    l = [Foo('hello'), Bar(), Bar()]        
    obj_count =0
    for item in l:
        if isinstance(item,Foo):
            yield item.name
            obj_count +=1

    if obj_count ==0:
        yield None

@pytest.mark.parametrize('obj_val', [val if val !=None else pytest.param(val, marks=pytest.mark.xfail(reason="There was not a Foo instance in the list")) for val in get_params() ])
def test_instance_in_list(obj_val):
    assert obj_val == 'foo', "Object content not matched"

如果在列表中找不到实例,测试将返回xfail,否则assert条件将检查对象内容

不美观是您的数据造成的,您的列表包含异构类型,因此无法解决此问题。
>       pytest.fail("There wasn't a Foo instance in the list")
E       Failed: There wasn't a Foo instance in the list

test_is_instance.py:21: Failed
================================== 1 failed in 0.03s ==================================
>               assert item.name == 'foo'
E               AssertionError: assert 'something else' == 'foo'
E                 - something else
E                 + foo

test_is_instance.py:18: AssertionError
================================== 1 failed in 0.03s ==================================
def get_params():
    l = [Foo('hello'), Bar(), Bar()]        
    obj_count =0
    for item in l:
        if isinstance(item,Foo):
            yield item.name
            obj_count +=1

    if obj_count ==0:
        yield None

@pytest.mark.parametrize('obj_val', [val if val !=None else pytest.param(val, marks=pytest.mark.xfail(reason="There was not a Foo instance in the list")) for val in get_params() ])
def test_instance_in_list(obj_val):
    assert obj_val == 'foo', "Object content not matched"