Почему не 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'
Любые идеи?
Ответы
Ответ 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