Как проверить значение поля для объекта, который должен быть в списке, смешанном с другими объектами разных классов? - PullRequest
0 голосов
/ 23 февраля 2020

Я использую pytest и пытаюсь проверить, имеет ли объект правильное содержимое в одном из его полей . Проблема, с которой я сталкиваюсь, заключается в том, что объект входит в список, где он может находиться в любой позиции и смешивается с объектами из разных классов , где это поле даже не существует.

Ниже приведен пример, который проверяет, что мне нужно. Пример работает должным образом, но я думаю, что это не очень удачное решение, потому что он тестирует 2 условия в тесте (экземпляр в списке и корректное содержимое, если он находит экземпляр), а также потому, что выполнение функции теста не кажется слишком clean.

У кого-нибудь есть советы по более элегантному и правильному способу проверки этого?

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 ()]

test_is_instance.py .                                                           [100%]

================================== 1 passed in 0.01s ==================================

Результаты бега с l = [Bar (), Bar (), Bar ()]

>       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 ==================================

Результаты бега с l = [Bar () , Foo ('другое имя'), Bar ()]

>               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 ==================================

Спасибо за ваш совет и помощь в поиске лучшего способа получения таких же результатов :-) !!

1 Ответ

0 голосов
/ 23 февраля 2020

Это может быть один из других подходов, если вы не хотите проверять наличие экземпляра в том же тесте.

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 проверит содержимое объекта

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...