Как утверждать, что диктат содержит другой диктовку без AssertDictContainsSubset в Python?

StackOverflow https://stackoverflow.com//questions/21058230

Вопрос

Я знаю assertDictContainsSubset можно сделать это в Python 2.7, но по какой-то причине это устарело в Python 3.2.Итак, есть ли способ утверждать, что один диктат содержит другой без assertDictContainsSubset?

Кажется, это нехорошо:

for item in dic2:
    self.assertIn(item, dic)

какой-нибудь другой хороший способ?Спасибо

Это было полезно?

Решение

>>> d1 = dict(a=1, b=2, c=3, d=4)
>>> d2 = dict(a=1, b=2)
>>> set(d2.items()).issubset( set(d1.items()) )
True
.

и наоборот вокруг:

>>> set(d1.items()).issubset( set(d2.items()) )
False
.

Ограничение: Словарь значений должны быть хмарированы.

Другие советы

Хотя я использую pteest, я нашел следующую идею в Комментарий .Это было очень здорово для меня, поэтому я подумал, что это может быть полезно здесь:

assert dict1.items() <= dict2.items()
.

для python 3 и

assert dict1.viewitems() <= dict2.viewitems()
.

для python 2.

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

Большая проблема с принятым ответом заключается в том, что она не работает, если у вас есть нематериальные значения в значениях объектов.Во-вторых, что вы не получаете полезного вывода - тест проходит или не удается, но не говорит вам, какое поле внутри объекта отличается.

Как таковое легче просто создать подмножество словаря, то тестируйте это.Таким образом, вы можете использовать метод TestCase.assertDictEquals(), который даст вам очень полезный отформатированный выход в ваш тестовый бегун, показывающий различие между фактическим и ожидаемым.

Я думаю, что самый приятный и пифитонический способ сделать это с простым словарем пониманием как таковой:

from unittest import TestCase


actual = {}
expected = {}

subset = {k:v for k, v in actual.items() if k in expected}
TestCase().assertDictEqual(subset, expected)
.

Примечание. Очевидно, что если вы управляете тестом в методе, который принадлежит дочерному классу, который наследует от тестирования (как вы почти наверняка должны быть), то это просто self.assertDictEqual(subset, expected)

Решение John1024 сработало для меня.Однако в случае сбоя он сообщит вам только False вместо того, чтобы показывать вам, какие ключи не совпадают.Итак, я попытался избежать устаревшего метода утверждения, используя другие методы утверждения, которые выдают полезные сообщения об ошибках:

    expected = {}
    response_keys = set(response.data.keys())
    for key in input_dict.keys():
        self.assertIn(key, response_keys)
        expected[key] = response.data[key]
    self.assertDictEqual(input_dict, expected)

Вот сравнение, которое работает, даже если у вас есть списки в словарях:

superset = {'a': 1, 'b': 2}
subset = {'a': 1}

common = { key: superset[key] for key in set(superset.keys()).intersection(set(subset.keys())) }

self.assertEquals(common, subset)
.

Это отвечает на немного более широкий вопрос, чем вы задаете, но я использую это в своих тестовых тестах, чтобы увидеть, соответствует ли container словарь содержит нечто, похожее на contained словарь.При этом проверяются ключи и значения.Кроме того, вы можете использовать ключевое слово 'ANYTHING' чтобы показать, что вам все равно, как это сочетается.

def contains(container, contained):
    '''ensure that `contained` is present somewhere in `container`

    EXAMPLES:

    contains(
        {'a': 3, 'b': 4},
        {'a': 3}
    ) # True

    contains(
        {'a': [3, 4, 5]},
        {'a': 3},
    ) # True

    contains(
        {'a': 4, 'b': {'a':3}},
        {'a': 3}
    ) # True

    contains(
        {'a': 4, 'b': {'a':3, 'c': 5}},
        {'a': 3, 'c': 5}
    ) # True

    # if an `contained` has a list, then every item from that list must be present
    # in the corresponding `container` list
    contains(
        {'a': [{'b':1}, {'b':2}, {'b':3}], 'c':4},
        {'a': [{'b':1},{'b':2}], 'c':4},
    ) # True

    # You can also use the string literal 'ANYTHING' to match anything
        contains(
        {'a': [{'b':3}]},
        {'a': 'ANYTHING'},
    ) # True

    # You can use 'ANYTHING' as a dict key and it indicates to match the corresponding value anywhere
    # below the current point
    contains(
        {'a': [ {'x':1,'b1':{'b2':{'c':'SOMETHING'}}}]},
        {'a': {'ANYTHING': 'SOMETHING', 'x':1}},
    ) # True

    contains(
        {'a': [ {'x':1, 'b':'SOMETHING'}]},
        {'a': {'ANYTHING': 'SOMETHING', 'x':1}},
    ) # True

    contains(
        {'a': [ {'x':1,'b1':{'b2':{'c':'SOMETHING'}}}]},
        {'a': {'ANYTHING': 'SOMETHING', 'x':1}},
    ) # True
    '''
    ANYTHING = 'ANYTHING'
    if contained == ANYTHING:
        return True

    if container == contained:
        return True

    if isinstance(container, list):
        if not isinstance(contained, list):
            contained = [contained]
        true_count = 0
        for contained_item in contained:
            for item in container:
                if contains(item, contained_item):
                    true_count += 1
                    break
        if true_count == len(contained):
            return True

    if isinstance(contained, dict) and isinstance(container, dict):
        contained_keys = set(contained.keys())
        if ANYTHING in contained_keys:
            contained_keys.remove(ANYTHING)
            if not contains(container, contained[ANYTHING]):
                return False

        container_keys = set(container.keys())
        if len(contained_keys - container_keys) == 0:
            # then all the contained keys are in this container ~ recursive check
            if all(
                contains(container[key], contained[key])
                for key in contained_keys
            ):
                return True

    # well, we're here, so I guess we didn't find a match yet
    if isinstance(container, dict):
        for value in container.values():
            if contains(value, contained):
                return True

    return False
Вместо этого вы можете использовать метод AssertGreaterequal ().

users = {'id': 28027, 'email': 'chungs.lama@gmail.com','created_at': '2005-02-13'}

data = {"email": "chungs.lama@gmail.com"}

self.assertGreaterEqual(user.items(), data.items())
.

в Python 3 и Python 2.7, вы можете создать набор «представление элемента» диктома, не копируя какие-либо данные.Это позволяет вам использовать операторы сравнения для проверки для подмножества отношений.

в Python 3, это выглядит как:

# Test if d1 is a sub-dict of d2
d1.items() <= d2.items()

# Get items in d1 not found in d2
difference = d1.items() - d2.items()
.

в Python 2.7. Вы можете использовать метод viewitems() вместо items() для достижения того же результата.

в Python 2.6 и ниже, ваша лучшая ставка состоит в том, чтобы повторить ключевые ключи в первом диктоме и проверять на включение во второй.

# Test if d1 is a subset of d2
all(k in d2 and d2[k] == d1[k] for k in d1)
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top