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

Распространенная ошибка при тестировании кода даты и времени - не устанавливать для текущего времени статическое время. Если код в пользовательском интерфейсе отображает сегодняшнюю дату и правильно протестирован, этот тест работает только до тех пор, пока текущее время не изменится слишком сильно. Javascript предоставляет встроенный объект Date, который позволяет получить текущее время с помощью конструкции без аргументов или вызова now() property.

Moment.js - популярная интерфейсная библиотека для обработки даты, которая обычно используется для управления, загрузки, форматирования и сдвига времени. Он использует пустой конструктор для получения текущего времени. Jest часто используется вместе с приложениями Moment и React. Кроме того, тестирование моментальных снимков Jest вводит новые зависимости от даты и времени, которые важно учитывать. Ниже приведен пример проблемного компонента, отображающего текущий день:

Первоначальный тест для TodayIntro component может выглядеть так:

Однако этот тест не состоится в любой день, кроме 23 января. Решение этой проблемы - переопределить функцию даты Javascript, чтобы она возвращала известную дату, с которой можно работать при написании тестов.

Этот код переопределяет конструктор Date для установки статической «текущей» даты:

Неэффективное решение - самостоятельно вычислить дату относительно текущего времени выполнения теста. Это неэффективный тест, потому что вы запускаете тот же код, что и тестируете, для проверки возвращаемого значения. Например, при тестировании путем сравнения отформатированных дат по моменту нельзя уловить, если код форматирования момента изменится с MMM на JAN вместо Jan.

Способы установить статическое время и часовой пояс для Jest / JS

  1. Используйте библиотеку для имитации объекта Date, чтобы вернуть статическую дату и часовой пояс (мы рекомендуем MockDate для простых случаев, но читайте дальше, чтобы узнать об альтернативах)
  2. Макет moment().format() для возврата статической строки
  3. Смоделируйте конструктор Date и функцию now(), чтобы вернуть статическое время

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

  • MockDate обеспечивает дополнительные функции для часовых поясов и прост в использовании
  • sinon предоставляет макеты даты и таймера (setTimeout и т. Д.)
  • Ручная установка макета может быть полезна в ограниченных средах, однако может стать довольно сложной.
  • jasmine (в шутку не входит), поставляется с jasmine.clock ()

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

Моментальный тест тоже несложно протестировать с фиктивными датами:

Поскольку фермент - отличная библиотека, простой пример фермента:

Как (лучше) проверить логику даты

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

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

Вот несколько неверных и часто неявных предположений о датах:

  1. Все клиенты находятся в одном часовом поясе и летнее время.
  2. Все клиенты находятся в часовом поясе разработчика.
  3. Длина названия месяца относительно похожа.
  4. Часы сервера всегда правильные
  5. Сервер знает настройки часового пояса и времени клиента.

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

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

Забегая вперед: хранение и дизайн даты и времени

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

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

Эти советы и подходы применимы не только к тестированию Javascript и Jest для определения даты и времени. Они также работают в контексте NodeJS и в целом над ключевыми вещами, которые нужно проверить в системах, которые обрабатывают дату и время в целом. Во многих случаях идеальным вариантом является сохранение времени на сервере в формате UTC (универсальное координированное время) с последующим преобразованием в местный часовой пояс на основе настроек клиента / браузера. Если клиент недоступен, сохранение времени в формате UTC и фактического часового пояса пользователя является эффективным способом согласованной обработки даты и времени.