Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как выполнить самоанализ assert в Python

Автор вопроса: Tom ChristieОтветов: 3

Я изучаю, как выполнить интроспекцию assert в Python таким же образом это py.test. Например...

>>> a = 1
>>> b = 2
>>> assert a == b
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AssertionError   # <--- I want more information here, eg 'AssertionError: 1 != 2'

Я вижу, что py.code библиотека имеет некоторые функции вокруг этого и я также видел этот ответ, в котором отмечалось, что sys.excepthook позволяет вы можете подключить любое поведение, которое вы хотите, к исключениям, но мне не ясно, как все это собрать.

  • Почему бы не использовать сам pytest? pylang 18.11.2016
  • @pylang У меня нет проблем с повторным использованием частей py.test, которые позволяют этому случиться, но я не могу просто использовать сам py.test. Для целей моего вопроса я говорю, что вы должны предположить, например. что я на самом деле не провожу тесты в этом контексте. Tom Christie 18.11.2016
  • @pylang Действительно ли возможно использовать утверждение pytest в общем контексте? Я предполагаю, что OP хочет использовать функциональность в автономной программе / библиотеке, например, для целей проверки. bluenote10 28.01.2019
  • Думаю, теперь я понимаю. Да, я не верю, что у pytes есть интерактивный режим (по крайней мере, в ноутбуках jupyter). Обычно я использовал nose именно из-за этой проблемы. pylang 29.01.2019

pythonpytestassert

Ответы

Ответ 1 · рейтинг 1 · Nihal Rp

Вы можете сделать что-то подобное, если хотите показать подробное сообщение об ошибке.

def assertion(a,b):
    try:
        assert a==b
    except AssertionError as e:
        e.args += ('some other', 'information',)
        raise

a=1
b=2
assertion(a,b)

Этот код даст следующий результат:

Traceback (most recent call last):
  File "tp.py", line 11, in <module>
    assertion(a,b)
  File "tp.py", line 4, in assertion
    assert a==b
AssertionError: ('some other', 'information')

Ответ 2 · рейтинг 1 · pylang

unittest assert дает дополнительную информацию (возможно, больше, чем вам нужно). На основе выступления Раймонда Хеттингера. Это частичный ответ, дающий только значения для a и b (последняя строка вывода), а не дополнительный самоанализ, который вы также ищете, который уникален для pytest.

import unittest

class EqualTest(unittest.TestCase):

    def testEqual(self, a, b):
        self.assertEqual(a, b)


a, b = 1, 2
assert_ = EqualTest().testEqual
assert_(a, b)

Вывод

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-4-851ce0f1f668> in <module>()
      9 a, b = 1, 2
     10 assert_ = EqualTest().testEqual
---> 11 assert_(a, b)

<ipython-input-4-851ce0f1f668> in testEqual(self, a, b)
      4
      5     def testEqual(self, a, b):
----> 6         self.assertEqual(a, b)
      7
      8

C:\Anaconda3\lib\unittest\case.py in assertEqual(self, first, second, msg)
    818         """
    819         assertion_func = self._getAssertEqualityFunc(first, second)
--> 820         assertion_func(first, second, msg=msg)
    821
    822     def assertNotEqual(self, first, second, msg=None):

C:\Anaconda3\lib\unittest\case.py in _baseAssertEqual(self, first, second, msg)
    811             standardMsg = '%s != %s' % _common_shorten_repr(first, second)
    812             msg = self._formatMessage(msg, standardMsg)
--> 813             raise self.failureException(msg)
    814
    815     def assertEqual(self, first, second, msg=None):

AssertionError: 1 != 2

Ответ 3 · bluenote10

Я не думаю, что просто воспроизвести интроспекцию assert в pytest в автономном контексте. Документы содержат еще несколько подробностей о том, как это работает:

pytest перезаписывает тестовые модули при импорте. Он делает это с помощью ловушки импорта для записи новых файлов pyc. В большинстве случаев это работает прозрачно. Однако, если вы сами возитесь с импортом, ловушка импорта может помешать. В этом случае просто используйте --assert = reinterp или --assert = plain. Кроме того, перезапись завершится с ошибкой, если она не сможет записать новые файлы pycs, то есть в файловой системе только для чтения или в zip-файле.

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы