Тестирование чувствительных ко времени приложений в Python - PullRequest
3 голосов
/ 19 апреля 2009

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

Вот одно из возможных решений: класс DateFactory , который предоставляет некоторые методы для генерации предсказуемой даты в тестировании и значения в реальном времени в производстве. Есть ли у вас какие-либо мысли по поводу этого подхода или вы пробовали что-то еще на практике?

Ответы [ 2 ]

3 голосов
/ 20 апреля 2009

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

def is_expired(self, check_date=None):
    _check_date = check_date or datetime.utcnow()
    return self.create_date + timedelta(days=15) < _check_date

По сути, это позволяет моему модульному тесту указывать собственную дату / время для проверки моей логики.

Аргумент в ссылочном блоге, похоже, состоит в том, что это портит API. Однако я сталкивался с ситуациями, в которых production использовались сценарии, требующие замены текущей даты / времени альтернативным значением. Другими словами, инверсионный подход управления в конечном итоге стал необходимой частью моего приложения.

1 голос
/ 03 июня 2009

В общем, я пытаюсь заставить производственный код принимать объекты даты в качестве входных данных (где семантика позволяет). Во многих ситуациях тестирования DateFactory, как вы описываете, - это то, что делают люди.

В Python вы также можете изменить методы статического модуля Datetime.now или Time.now напрямую. Вы должны быть осторожны, чтобы заменить их в тестовой части. Это особенно полезно, когда вы не можете (или неловко) изменить класс, который вы тестируете.

Для этого у вас есть

   def setUp(self) 
      self.oldNow = Datetime.now
      Datetime.now = self._fakenow
      ...

   def tearDown(self)
      Datetime.now = self.oldNow

Я делаю замены в последнюю очередь, если есть малейшая вероятность, что метод установки потерпит неудачу.

Во многих случаях пользовательскую DateFactory безопаснее использовать, особенно если вам приходится беспокоиться о людях, забывающих порцию tearDown.

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