Почему требуется assertDictEqual, если dicts можно сравнить с '=='?

Честно говоря, я всегда использовал assertDictEqual, потому что когда-то, когда я его не использовал, я получил информацию, что равные dicts не совпадают.

Но... Я знаю, что dicts можно сравнить с оператором ==:

>>> {'a':1, 'b':2, 'c': [1,2]} == {'b':2, 'a':1, 'c': [1,2]}
True

Где мне действительно может понадобиться assertDictEqual?

Ответ 1

В принципе, он позволяет unittest давать вам больше информации о том, почему тест не удался. Сравните эти два теста:

class DemoTest(unittest.TestCase):

    D1 = {'a': 1, 'b': 2, 'c': [1, 2]}
    D2 = {'a': 1, 'b': 2, 'c': [1]}

    def test_not_so_useful(self):
        assert self.D1 == self.D2

    def test_useful(self):
        self.assertDictEqual(self.D1, self.D2)

И их результаты:

Failure
Traceback (most recent call last):
  File "...x.py", line 86, in test_not_so_useful
    assert self.D1 == self.D2
AssertionError

против

Failure
Traceback (most recent call last):
  File "...x.py", line 80, in test_useful
    self.assertDictEqual(self.D1, self.D2)
AssertionError: {'a': 1, 'c': [1, 2], 'b': 2} != {'a': 1, 'c': [1], 'b': 2}
- {'a': 1, 'b': 2, 'c': [1, 2]}
?                         ---

+ {'a': 1, 'b': 2, 'c': [1]}

В последнем вы можете точно видеть, в чем разница, вам не нужно самостоятельно это решать. Обратите внимание, что вы можете просто использовать стандартный assertEqual вместо assertDictEqual с тем же результатом; за документы

... его обычно не нужно напрямую ссылаться на эти методы.

Ответ 2

Я предполагаю, что это происходит в контексте unittesting. Метод assertDictEqual будет не только сравнивать dicts и оценивать True или False, но может дать вам дополнительную информацию. Такие, как точные различия между двумя диктофонами.

Кроме того, в хорошей IDE unittests будет хорошо интегрироваться. Вы можете просто добавить TestCase, использовать assertDictEqual, и среда IDE найдет и проведет тест для вас. Затем вывод выводится в удобном для чтения формате. Это может сэкономить вам много шаблонов.

Меня очень интересовал бы случай, когда два равных dicts не равны по сравнению с "==".

Ответ 3

Это часть более широкого вопроса:

Почему в unittest есть все специальные утверждения?

Ответ заключается в том, что основная задача методов UnitTest assert * состоит в том, чтобы дать вам значимый вывод при неудачном завершении теста. Посмотрите на код модуля unittest - это действительно то, что они делают (только то, что они делают??)

Учитывая, что Python является динамическим языком с легким самоанализом, зачем все это? И ответ таков: "потому что unitest был портирован из пакета Java junit, и то, как они это делали в Java (и, вероятно, пришлось это сделать, учитывая, насколько сложнее/невозможно это проанализировать во время выполнения).

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

Он также включает в себя множество отличных функций для параметризованного тестирования, приспособлений, конфигурации тестирования, макетов и т.д.

Если вы находитесь в проекте, который уже использует unitest - вы все равно можете запускать свои тесты с помощью pytest и пользоваться многими его преимуществами.