Python: как создать положительный тест для процедур?

#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:

Не видя фактического кода, трудно догадаться, однако я сделаю некоторые предположения:

  1. Логика в статических методах детерминирована.
  2. После выполнения некоторых вычислений для входного значения есть результат, и с этим результатом выполняется некоторая операция.
  3. 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)
  

В модульном тестировании я проверю следующее:

  1. open был вызван.
  2. Вычислено ожидаемое имя файла.
  3. open был вызван в write режиме.
  4. 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 .