Есть ли веская причина ловить исключения в транзакциях unittest? - PullRequest
0 голосов
/ 23 апреля 2019

Модуль unittest чрезвычайно хорош для обнаружения проблем в коде.Я понимаю идею выделения и тестирования частей кода с помощью утверждений:

self.assertEqual(web_page_view.func, web_page_url)

Но помимо этих утверждений у вас также может быть некоторая логика перед ним, в том же методе тестирования, который мог быесть проблемы.

Мне интересно, если ручная обработка исключений когда-либо учитывается внутри методов подкласса TestCase.

Потому что, если я оберну блок в try-catch, если что-тоне проходит, тест возвращает OK и не дает сбоя:

    def test_simulate_requests(self):
        """
        Simulate requests to a url
        """
        try:
           response = self.client.get('/adress/of/page/')
           self.assertEqual(response.status_code, 200)
        except Exception as e:
            print("error: ", e)

Следует ли всегда избегать обработки исключений в таких тестах?

Ответы [ 2 ]

1 голос
/ 23 апреля 2019

Есть два «плохих» состояния теста: «Сбой» (когда одно из утверждений не выполнено) и «Ошибка» (когда сам тест не пройден - ваш случай).

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

Если вам нужно утверждать, что какой-то проверенный код вызывает исключение, вы должны использовать with self.assertRaises(ExpectedError)

Если какой-то код в тесте вызывает исключение - лучше узнать его по результату «Ошибка»чем «ОК, все тесты пройдены»

Если ваша логика тестирования действительно предполагает, что в самом тесте может произойти сбой, и это нормальное поведение - возможно, тест неверный.Может быть, вы должны использовать mocks (https://docs.python.org/3/library/unittest.mock.html) для имитации вызова API или чего-то еще.

В вашем случае, даже если тест не пройден, вы ловите его с голым исключением, и говорите: «Хорошо, продолжайте". В любом случае реализация неверна.

Наконец: нет, не должно быть ничего, кроме как в ваших тестовых примерах

PS Лучше вызывать ваши тестовые функции с test_what_you_want_to_test_name, в этом случае, вероятно, test_successful_requestбыло бы хорошо.

0 голосов
/ 25 апреля 2019

Первая часть ответа:

Как вы правильно сказали, перед самим тестом должна быть какая-то логика.Код, принадлежащий модульному тесту, может быть разбит на четыре части (я использую терминологию Месароша в следующем): настройка, тренировка, проверка, разборка.Часто код тестового примера структурирован таким образом, что код для четырех частей четко разделен и идет в таком точном порядке - это называется четырехфазным тестовым шаблоном.

Фаза упражнения является сердцемтест, где выполняется функциональность, которая должна быть проверена в тесте.Настройка гарантирует, что это происходит в четко определенном контексте.Итак, в этой терминологии вы описали ситуацию, когда во время установки что-то дает сбой.Это означает, что не соблюдаются предварительные условия, которые требуются для осмысленного выполнения проверяемой функциональности.

Это обычная ситуация, и это означает, что вам необходимо уметь различать трирезультаты теста: тест может быть успешно пройден, он может быть неудачным или просто бессмысленным.

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

import unittest
class TestException(unittest.TestCase):
   def test_skipTest_shallSkip(self):
      self.skipTest("Skipped because skipping shall be demonstrated.")

Вторая часть ответа:

Кажется, в вашем тесте есть некоторые недетерминированные элементы.self.client.get может выдавать исключения (но только иногда - иногда нет).Это означает, что у вас нет контекста во время выполнения теста под контролем.В модульном тестировании вы должны попытаться избежать этой ситуации.Ваши тесты должны иметь детерминированное поведение.

Один из типичных способов добиться этого - изолировать ваш код от компонентов, которые несут ответственность за недетерминизм, и во время тестирования заменить эти компоненты на фиктивные.Поведение макетов находится под полным контролем тестового кода.Таким образом, если ваш код использует какой-либо компонент для доступа к сети, вы бы посмеялись над ним.Затем в некоторых тестовых примерах вы можете указать макету имитировать успешное сетевое взаимодействие, чтобы увидеть, как ваш компонент справляется с этим, а в других тестах вы проинструктируйте макет, чтобы имитировать сбой сети, чтобы увидеть, как ваш компонент справляется с этой ситуацией.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...