Как улучшить тест, который падает в выходные дни
Что проверяют
Умеете ли вы найти скрытую зависимость теста от текущей даты и убрать её из кода, а не из расписания CI. Следом обычно просят показать, как подменить время в тесте и что делать с часовыми поясами.
Как отвечать
Первая гипотеза: тест или код под ним читает DateTime.Now напрямую, а логика зависит от дня недели. Это рабочие дни, срок «через три рабочих дня», тарифы выходного дня. Вечер пятницы по UTC уже может быть субботой по местному времени агента. Проверить быстро: прогнать тест с зафиксированной субботней датой.
Исправление в коде, а не в тесте:
- абстракция времени: с .NET 8 есть встроенный
TimeProvider. Сервис получает его через DI и зовётGetUtcNow(), в продакшене регистрируетсяTimeProvider.System; - подмена в тесте:
FakeTimeProviderиз пакетаMicrosoft.Extensions.TimeProvider.Testingвыставляет нужную дату черезSetUtcNowи двигает время черезAdvance. На старых версиях заводят свой интерфейсIClock; - явные сценарии: вместо теста, который зависит от дня запуска, параметризованный тест на каждый важный день (
[Theory]с[InlineData]в xUnit,[TestCase]в NUnit): пятница, суббота, воскресенье, понедельник, праздник; - часовые пояса: хранить и сравнивать в UTC или
DateTimeOffset, в местное время переводить на границе черезTimeZoneInfo. Иначе тест начнёт падать уже в зависимости от пояса агента CI; - внешние причины: если время ни при чём, проверить то, что меняется по выходным: ночные джобы, очистку тестовой базы, внешние сервисы с окном обслуживания.
Где спотыкаются
Отключают тест на выходные или переносят прогон на будни. Баг остаётся в продакшене, и пользователь в субботу получит ту же ошибку.
Подменяют DateTime.Now через Microsoft Fakes или другие шимы вместо внедрения зависимости от времени. Это хрупко и работает не во всех окружениях.
Списывают падение на нестабильность и добавляют ретраи. Тест, который падает строго по субботам, детерминирован, и повторный запуск его не спасёт.