Я изучаю, как выполнить интроспекцию 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
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-файле.
Похоже, что для работы с произвольными модулями потребуются некоторые хаки, поэтому вам, вероятно, лучше использовать решение, предложенное в других ответах.