Почему модульные тесты становятся нестабильными на примере функции, использующей текущее время: "def is_business_hour(): return 9 <= datetime.now().hour

24 Сен в 12:18
10 +1
0
Ответы
1

Модульные тесты могут становиться нестабильными по ряду причин, особенно когда они зависят от динамически изменяемых данных, например, от текущего времени. Функция is_business_hour, основанная на datetime.now, будет возвращать разные результаты в зависимости от времени выполнения теста, что делает её трудной для тестирования.

Проблема с нестабильностью тестов

В данном случае, если тест выполняется в пределах рабочего времени например,между9:00и17:59например, между 9:00 и 17:59например,между9:00и17:59, тест пройдет, но если время выполнения изменится на 18:00, тест будет провален. Это создает проблемы, так как один и тот же тест может давать разные результаты в зависимости от времени.

Тестируемая версия функции

Чтобы сделать функцию is_business_hour более тестируемой, стоит инкапсулировать логику получения текущего времени, позволяя тестам легко подменять её. Одним из подходов является передача времени в качестве параметра. Например:

from datetime import datetime
def is_business_hournow=Nonenow=Nonenow=None:
if now is None:
now = datetime.now return 9 <= now.hour < 18

Теперь функция принимает значение времени и может использовать текущее время по умолчанию, если параметр не передан.

Тестирование функции

Теперь можно написать модульные тесты, передавая разные значения для now:

import unittest
from datetime import datetime
class TestBusinessHourunittest.TestCaseunittest.TestCaseunittest.TestCase:
def test_business_hour_morningselfselfself:
self.assertTrueisbusinesshour(datetime(2023,10,10,10,0,0))is_business_hour(datetime(2023, 10, 10, 10, 0, 0))isb usinessh our(datetime(2023,10,10,10,0,0))
def test_business_hour_eveningselfselfself:
self.assertFalseisbusinesshour(datetime(2023,10,10,19,0,0))is_business_hour(datetime(2023, 10, 10, 19, 0, 0))isb usinessh our(datetime(2023,10,10,19,0,0))
def test_business_hour_boundary_startselfselfself:
self.assertTrueisbusinesshour(datetime(2023,10,10,9,0,0))is_business_hour(datetime(2023, 10, 10, 9, 0, 0))isb usinessh our(datetime(2023,10,10,9,0,0))
def test_business_hour_boundary_endselfselfself:
self.assertFalseisbusinesshour(datetime(2023,10,10,18,0,0))is_business_hour(datetime(2023, 10, 10, 18, 0, 0))isb usinessh our(datetime(2023,10,10,18,0,0))
if __name__ == '__main__':
unittest.mainПриёмы для интеграционного тестирования

Инъекция времени: Как показано выше, можно передавать время в функцию в качестве параметра, что позволяет легко тестировать разные временные рамки, без зависимости от реального времени.

Фикстуры: В тестовых библиотеках, таких как pytest, можно использовать фикстуры, чтобы задавать общее состояние или предустанавливать данные для тестов, включая текущее время.

Мокирование: Для тестов можно использовать библиотеки вроде unittest.mock для подмены datetime.now на статическое значение, что позволяет создать контрольный тест с фиксированным временем.

Пример с мокированием:

from unittest.mock import patch
class TestBusinessHourWithMockunittest.TestCaseunittest.TestCaseunittest.TestCase:
@patch′datetime.datetime′'datetime.datetime'datetime.datetime def test_business_hourself,mockdatetimeself, mock_datetimeself,mockd atetime:
# Настраиваем мок для возвращения фиксированного времени
mock_datetime.now.return_value = datetime2023,10,10,10,0,02023, 10, 10, 10, 0, 02023,10,10,10,0,0 self.assertTrueisbusinesshour()is_business_hour()isb usinessh our()
@patch′datetime.datetime′'datetime.datetime'datetime.datetime def test_outside_business_hourself,mockdatetimeself, mock_datetimeself,mockd atetime:
mock_datetime.now.return_value = datetime2023,10,10,19,0,02023, 10, 10, 19, 0, 02023,10,10,19,0,0 self.assertFalseisbusinesshour()is_business_hour()isb usinessh our()
if __name__ == '__main__':
unittest.main

Таким образом, используя данные подходы, вы можете создавать стабильные и предсказуемые тесты для функций, которые зависят от текущего времени.

24 Сен в 12:31
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир