Подтвердить что ты не робот

Почему не assertRaises ловить мою ошибку атрибута с помощью python unittest?

Я пытаюсь запустить этот тест: self.assertRaises(AttributeError, branch[0].childrennodes) и branch[0] не имеет атрибута childrennodes, поэтому он должен метать AttributeError, который должен быть assertRaises, но когда Я запускаю тест, тест терпит неудачу, потому что он бросает AttributeError.

Traceback (most recent call last):
  File "/home/tttt/../tttt/tests.py", line 504, in test_get_categories_branch
    self.assertRaises(AttributeError, branch[0].children_nodes)
AttributeError: 'Category' object has no attribute 'children_nodes'

Любые идеи?

4b9b3361

Ответ 1

Я думаю, что его, потому что assert поднимает, только принимает вызываемый. Он проверяет, не вызывает ли вызываемый вызов исключение, а не сам оператор.

self.assertRaises(AttributeError, getattr, branch[0], "childrennodes")

должен работать.

EDIT:

Как THC4k правильно говорит, что он собирает инструкции во время сбора данных и будет ошибкой, а не во время тестирования.

Также это причина, по которой мне нравится нос, у нее есть декоратор (рейзы), который полезен и ясен для таких тестов.

@raises(AttributeError)
def test_1(self)
    branch[0].childrennodes

Ответ 2

Когда тест запущен, перед вызовом self.assertRaises, Python должен найти значение всех аргументов метода. При этом он оценивает branch[0].children_nodes, что вызывает атрибут AttributeError. Поскольку мы еще не вызывали assertRaises, это исключение не попадает, что приводит к сбою теста.

Решение состоит в том, чтобы обернуть branch[0].children_nodes в функцию или лямбда:

self.assertRaises(AttributeError, lambda: branch[0].children_nodes)

assertRaises также может использоваться как менеджер контекста (с Python 2.7 или в пакете PyPI 'unittest2'):

with self.assertRaises(AttributeError):
    branch[0].children_nodes
    # etc

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

Он может предоставить вам доступ к поднятому исключению для дальнейшей обработки, если необходимо:

with self.assertRaises(AttributeError) as cm:
    branch[0].children_nodes

self.assertEquals(cm.exception.special_attribute, 123)

Ответ 3

pytest также имеет аналогичный декоратор:

from pytest import raises

def test_raising():
    with raises(AttributeError):
        branch[0].childrennodes