Я уже писал про пакет synctest и его возможности. Это была одна из главных фишек Go 1.25, здорово облегчившая тестирование конкурентного кода. Главный минус данного пакета, на мой взгляд, это его слабая интегрированность в стандартную библиотеку. И, похоже, эту проблему наконец решено начать исправлять.
Большинство из нас работает с HTTP-серверами (включая gRPC, который является сабсетом HTTP/2) в том или ином виде. Для тестирования этих серверов у нас есть пакет net/http/httptest, который позволяет легко поднять тестовый HTTP-сервер, отвечающий на запросы, используя реальный loopback-интерфейс. Запущенный тестовый сервер также легко создаёт подключенного к себе клиента, который, в свою очередь, работает одинаково хорошо с обычным соединением и TLS-режимом без сложных махинаций с корнем сертификатов. Однако у этого подхода есть минус: так как он использует реальный сетевой интерфейс и порт (и, как следствие, сокет), пакет synctest с ним несовместим.
Проблемой озаботился Дэмиен Нил (автор самого
synctest) и предложил добавить в пакет httptest новую функцию: NewTestServer. Суть заключается в том, что если на полученном сервере не вызывать метод Start, то все запросы пойдут через in-memory-шину, реализованную на каналах. Таким образом уходит IO, и процесс становится контролируемым через synctest.При этом все запросы клиента, полученного от созданного сервера, вне зависимости от целевого адреса, будут уходить на сервер, породивший клиента (в отличие от клиентов для обычных тестовых серверов, где запросы могут уходить и на сторонние адреса). Если же на полученном сервере вызвать метод
Start, он будет вести себя так же, как и раньше вёл себя тестовый сервер - поднимет сокет слушающий на loopback-интерфейсе.Вместе с
synctest такой подход позволяет создавать серверные юнит-тесты, где можно отслеживать статус сервера, хендлеров, прочих сущностей в любой момент времени без лишних костылей. И ловить утечку горутин после завершения тестов.Текущий статус: accepted, но я не уверен, что фича попадет в 1.27 из-за скорого фича-фриза.