Я отправляю этот ответ, потому что мой интерфейс администратора Virtualmin / Webmin решил, что было бы неплохо отключить мой PHP-движок. Я нашел время, чтобы найти решение, поэтому я решил поделиться с ним вы, ребята:
Также не забудьте проверить, что ни один из ваших конфигурационных файлов вашего сайта, связанных с этим конкретным хостом или виртуальным хостом, не имеет в них php_admin_value, которые отключают PHP, например:
php_admin_value engine Off
В случае сомнений прокомментируйте это ...
# php_admin_value engine Off
И перезагрузите свой веб-сервер.
Ваш код должен следовать этому шаблону (это тест стиля модуля unittest):
def test_afunction_throws_exception(self):
try:
afunction()
except ExpectedException:
pass
except Exception as e:
self.fail('Unexpected exception raised:', e)
else:
self.fail('ExpectedException not raised')
В Python & lt; 2.7 эта конструкция полезна для проверки определенных значений в ожидаемом исключении. Функция unittest assertRaises
проверяет, было ли возбуждено исключение.
Начиная с Python 2.7 вы можете использовать диспетчер контекста, чтобы получить доступ к фактическому объекту Exception:
import unittest
def broken_function():
raise Exception('This is broken')
class MyTestCase(unittest.TestCase):
def test(self):
with self.assertRaises(Exception) as context:
broken_function()
self.assertTrue('This is broken' in context.exception)
if __name__ == '__main__':
unittest.main()
http://docs.python.org/dev/library/unittest. html # unittest.TestCase.assertRaises
В Python 3.5 вы должны обернуть context.exception
в str
, иначе вы получите TypeError
self.assertTrue('This is broken' in str(context.exception))
context.exception
не дает сообщения; это тип.
– LateCoder
25 February 2016 в 17:55
import unittest2
, вам нужно использовать str()
, т. Е. self.assertTrue('This is broken' in str(context.exception))
.
– Sohail Si
19 January 2017 в 02:00
Вы можете использовать assertRaises из модуля unittest
import unittest
class TestClass():
def raises_exception(self):
raise Exception("test")
class MyTestCase(unittest.TestCase):
def test_if_method_raises_correct_exception(self):
test_class = TestClass()
# note that you dont use () when passing the method to assertRaises
self.assertRaises(Exception, test_class.raises_exception)
Код в моем предыдущем ответе можно упростить до:
def test_afunction_throws_exception(self):
self.assertRaises(ExpectedException, afunction)
И если afunction принимает аргументы, просто передайте их в assertRaises следующим образом:
def test_afunction_throws_exception(self):
self.assertRaises(ExpectedException, afunction, arg1, arg2)
Как вы проверяете, что функция Python генерирует исключение?
Как написать тест, который выходит из строя, только если функция не генерирует ожидаемое исключение?
< / blockquote>Short Answer:
Использовать метод
self.assertRaises
в качестве менеджера контекста:def test_1_cannot_add_int_and_str(self): with self.assertRaises(TypeError): 1 + '1'
Демонстрация
довольно легко продемонстрировать в оболочке Python.
Библиотека
unittest
В Python 2.7 или 3:
import unittest
В Python 2.6 вы можете установить backport из 2.7's
unittest
, называемой unittest2 , и просто псевдоним, который какunittest
:import unittest2 as unittest
Примеры тестов
Теперь вставьте в свою оболочку Python следующую тест безопасности типа Python:
class MyTestCase(unittest.TestCase): def test_1_cannot_add_int_and_str(self): with self.assertRaises(TypeError): 1 + '1' def test_2_cannot_add_int_and_str(self): import operator self.assertRaises(TypeError, operator.add, 1, '1')
В тестовом режиме в качестве менеджера контекста используется
assertRaises
, который гарантирует, что ошибка будет правильно захвачена и очищена, при записи.Мы могли бы также написать без менеджера контекста, см. тест два. Первым аргументом будет тип ошибки, которую вы ожидаете поднять, второй аргумент, тестируемая функция, а остальные аргументы args и ключевого слова будут переданы этой функции.
Я думаю, что это гораздо проще, легко читаемо и поддерживается только для использования диспетчера контекстов.
Запуск тестов
Для запуска тестов:
unittest.main(exit=False)
В Python 2.6 вам, вероятно, понадобится следующее :
unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromTestCase(MyTestCase))
И ваш терминал должен вывести следующее:
.. ---------------------------------------------------------------------- Ran 2 tests in 0.007s OK <unittest2.runner.TextTestResult run=2 errors=0 failures=0>
И мы видим, что, как мы ожидаем, попытка добавить
1
и'1'
приведет кTypeError
.
Для получения более подробного вывода попробуйте следующее:
unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromTestCase(MyTestCase))
Я только что обнаружил, что библиотека Mock предоставляет метод assertRaisesWithMessage () (в подклассе unittest.TestCase), который будет проверять не только то, что ожидаемое исключение будет поднято, но и что оно поднято с ожидаемым сообщением:
from testcase import TestCase
import mymod
class MyTestCase(TestCase):
def test1(self):
self.assertRaisesWithMessage(SomeCoolException,
'expected message',
mymod.myfunc)
from: http://www.lengrand.fr/2011/12/pythonunittest-assertraises-raises-error/
Во-первых, вот соответствующая (все еще dum : p) в файле dum_function.py:
def square_value(a):
"""
Returns the square value of a.
"""
try:
out = a*a
except TypeError:
raise TypeError("Input should be a string:")
return out
Вот тест, который нужно выполнить (только этот тест вставлен):
import dum_function as df # import function module
import unittest
class Test(unittest.TestCase):
"""
The class inherits from unittest
"""
def setUp(self):
"""
This method is called before each test
"""
self.false_int = "A"
def tearDown(self):
"""
This method is called after each test
"""
pass
#---
## TESTS
def test_square_value(self):
# assertRaises(excClass, callableObj) prototype
self.assertRaises(TypeError, df.square_value(self.false_int))
if __name__ == "__main__":
unittest.main()
Теперь мы готовы проверьте нашу функцию! Вот что происходит при попытке выполнить тест:
======================================================================
ERROR: test_square_value (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_dum_function.py", line 22, in test_square_value
self.assertRaises(TypeError, df.square_value(self.false_int))
File "/home/jlengrand/Desktop/function.py", line 8, in square_value
raise TypeError("Input should be a string:")
TypeError: Input should be a string:
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
ТипError активирован и генерирует ошибку теста. Проблема в том, что это именно то, что мы хотели: s.
Чтобы избежать этой ошибки, просто запустите функцию, используя лямбда в тестовом вызове:
self.assertRaises(TypeError, lambda: df.square_value(self.false_int))
Конечный вывод :
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Отлично!
... и для меня тоже отлично!
Thansk много г-н Жюльен Ленгранд-Ламберт
self.assertRaises(TypeError, df.square_value(self.false_int))
вызывает метод и возвращает результат. Вы хотите передать метод и любые аргументы и позволить unittest называть его: self.assertRaises(TypeError, df.square_value, self.false_int)
– Roman Kutlak
8 August 2013 в 13:36
Я использую doctest [1] почти везде, потому что мне нравится тот факт, что я документирую и тестирую свои функции одновременно.
Посмотрите на этот код:
def throw_up(something, gowrong=False):
"""
>>> throw_up('Fish n Chips')
Traceback (most recent call last):
...
Exception: Fish n Chips
>>> throw_up('Fish n Chips', gowrong=True)
'I feel fine!'
"""
if gowrong:
return "I feel fine!"
raise Exception(something)
if __name__ == '__main__':
import doctest
doctest.testmod()
Если вы помещаете этот пример в модуль и запускаете его из командной строки, оба тестовых примера оцениваются и проверяются.
[1] Документация на Python: 23.2 doctest - Тестирование интерактивных примеров Python
Вы можете создать свой собственный contextmanager
, чтобы проверить, было ли возбуждено исключение.
import contextlib
@contextlib.contextmanager
def raises(exception):
try:
yield
except exception as e:
assert True
else:
assert False
И тогда вы можете использовать raises
следующим образом:
with raises(Exception):
print "Hola" # Calls assert False
with raises(Exception):
raise Exception # Calls assert True
Если вы используете pytest
, эта вещь уже реализована. Вы можете сделать pytest.raises(Exception)
:
Пример:
def test_div_zero():
with pytest.raises(ZeroDivisionError):
1/0
И результат:
pigueiras@pigueiras$ py.test
================= test session starts =================
platform linux2 -- Python 2.6.6 -- py-1.4.20 -- pytest-2.5.2 -- /usr/bin/python
collected 1 items
tests/test_div_zero.py:6: test_div_zero PASSED
Посмотрите на метод assertRaises модуля unittest
.
assertRaises
, вы получите ERROR вместо FAIL. – unflores 21 January 2015 в 13:52myfunc
вам нужно добавить их в качестве аргументов в вызов assertRaises. См. Ответ Дэрила Спитцера. – cbron 21 February 2018 в 17:43