Pytest, как издеваться над Threading.Timer - PullRequest
0 голосов
/ 12 января 2019

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

Конечно, эта проблема случалась раньше. Как я могу "уснуть" на моем модульном тесте или как-то посмеяться над течением времени?

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

Любой совет по этому вопросу?

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

Если вы посмотрите на источник threading.Timer, вы увидите, что эффект задержки исходит от Timer (который сам по себе Thread) просто вызывает .wait() на threading.Event объект.

Вы можете использовать unittest.mock или pytest-mock, чтобы заменить реализацию Event.wait() на реализацию, которая на самом деле ничего не ждет.

0 голосов
/ 03 февраля 2019

Обновление: Ваш комментарий наконец-то проясняет, что вы намерены достичь, а именно не нужно ждать реальных 60-х в вашем тесте. Уже есть некоторые обсуждения темы, как выполнить юнит-тестирование кода, который работает с таймерами:

Основная идея состоит в том, чтобы использовать метод, называемый «инверсия управления»: вместо того, чтобы позволить тестируемой системе (SUT) контролировать время, измените конструкцию так, чтобы тест мог это сделать. Есть много разных способов, например, а) превратить объект таймера в аргумент, или б) получить к нему доступ в SUT с помощью вспомогательного метода, который может быть переопределен тестом, или получить SUT из фабрики ( который вы заменяете во время тестирования), или, чтобы тест мог перезаписать его с помощью метода установки и т. д.

Оригинальный ответ (сфокусирован на другом аспекте):

Из вашего вопроса и комментария я заключаю, что для ваших тестов вы соглашаетесь с тем, что выполнение теста действительно займет около 60 секунд (цитата: «Мне нужно проверить, что задача действительно была выполнена через 60 секунд» и «Как» могу ли я "уснуть" на моем модульном тесте [...] "). Вы хотите проверить, что программа использует таймер для выполнения задачи - это скорее сценарий интеграционного тестирования, чем сценарий модульного теста.

Описание теста пока не очень точное, поэтому я сделаю некоторые предположения. Предположим, вы хотите проверить, что «задание» не выполняется, скажем, до 59-х, но также и не позднее, чем, скажем, 61-х. Есть несколько способов добиться этого. Один простой подход заключается в том, чтобы фактически использовать режим сна для 58 секунд, проверить, что задача еще не выполнена (тестовый пример 1), и иметь другой тестовый случай с режимом сна 61 и проверить, что задача была выполнена. Но из-за различных эффектов он не полностью устойчив, как вы уже упоминали. Вы можете сделать его более надежным, увеличив временной интервал.

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

Я бы сказал, поскольку этот вопрос касается программ на python, вам просто придется жить с определенной степенью неточности. Даже в системах реального времени с программами на C или даже на ассемблере достижение высокого уровня точности является сложной задачей, но мы говорим здесь о различных уровнях точности (микросекунды и лучше).

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