#python #unit-testing #static-methods #assert #procedure
#python #модульное тестирование #статические методы #утверждать #процедура
Вопрос:
У меня есть класс с некоторыми @staticmethod
‘s, которые являются процедурами, поэтому они ничего не возвращают / их возвращаемый тип None
.
Если они терпят неудачу во время выполнения, они выдают Exception
.
Я хочу unittest
этот класс, но я борюсь с разработкой положительных тестов.
Для отрицательных тестов эта задача проста:
assertRaises(ValueError, my_static_method(*args))
assertRaises(MyCustomException, my_static_method(*args))
…но как мне создать положительные тесты? Должен ли я перепроектировать свои процедуры, чтобы они всегда возвращались True
после выполнения, чтобы я мог использовать assertTrue
их?
Комментарии:
1. Просто вызовите функцию без каких-либо утверждений. Если он выдает исключение, тест завершится неудачно.
2. Итак, если процедура не вызывает исключения, она прошла успешно? Затем просто вызовите процедуру без обертки try / catch .
3. Да; если процедура не вызывает исключения, она прошла успешно. Если возникает исключение, оно перехватывается другими классами, которые используют процедуры. Таким образом, любое исключение будет сгенерировано в методе unittest, если произойдет что-то плохое.
4. Как насчет
assertIsNone
? Как вы сами сказали, это то,None
что должна возвращать «процедура». Так что мне кажетсяassertIsNone
, что это проверит именно то, что нужно.5. У процедуры есть побочный эффект, или нет смысла ее вызывать. Проверьте, возникает ли побочный эффект.
Ответ №1:
Не видя фактического кода, трудно догадаться, однако я сделаю некоторые предположения:
- Логика в статических методах детерминирована.
- После выполнения некоторых вычислений для входного значения есть результат, и с этим результатом выполняется некоторая операция.
- python3.4 (макет развивался и менялся в течение последних нескольких версий)
Чтобы протестировать код, нужно проверить, что, по крайней мере, в конце он дает ожидаемые результаты. Если возвращаемого значения нет, результат обычно сохраняется или отправляется куда-либо. В этом случае мы можем проверить, что метод, который сохраняет или отправляет результат, вызывается с ожидаемыми аргументами.
Это можно сделать с помощью инструментов, доступных в mock
пакете, который стал частью unittest
пакета.
например, следующий статический метод в my_package/my_module.py
:
import uuid
class MyClass:
@staticmethod
def my_procedure(value):
if isinstance(value, str):
prefix = 'string'
else:
prefix = 'other'
with open('/tmp/%s_%s' % (prefix, uuid.uuid4()), 'w') as f:
f.write(value)
В модульном тестировании я проверю следующее:
open
был вызван.- Вычислено ожидаемое имя файла.
open
был вызван вwrite
режиме.write()
Метод дескриптора файла был вызван с ожидаемым аргументом.
Unittest:
import unittest
from unittest.mock import patch
from my_package.my_module import MyClass
class MyClassTest(unittest.TestCase):
@patch('my_package.my_module.open', create=True)
def test_my_procedure(self, open_mock):
write_mock = open_mock.return_value.write
MyClass.my_procedure('test')
self.assertTrue(open_mock.call_count, 1)
file_name, mode = open_mock.call_args[0]
self.assertTrue(file_name.startswith('/tmp/string_'))
self.assertEqual(mode, 'w')
self.assertTrue(write_mock.called_once_with('test'))
Ответ №2:
Если ваши методы что-то делают, то я уверен, что там должна быть логика. Давайте рассмотрим этот фиктивный пример:
cool = None
def my_static_method(something):
try:
cool = int(something)
except ValueError:
# logs here
для отрицательного теста у нас есть:
assertRaises(ValueError, my_static_method(*args))
и для возможного теста мы можем проверить cool:
assertIsNotNone(cool)
Итак, вы проверяете my_static_method
, влияет ли вызов на cool
.