Этот крутой вопрос поднял мой добрый коллега Паша Кириллин. И я в очередной раз убедился, насколько же я дуболом 🤖.
💩 Обычно, если я хочу написать тесты, которым зачем-то нужна реальная база, то я втупую напишу docker-compose.yaml с конфигурацией этой базы. И каждый раз при запуске дергаю docker compose up. В общем, довольно грубый метод.
А вот Паша посидел разок и задумался, а как бы это сделать автоматизированно, чтобы не пришлось делать docker compose up? И сразу нашел решение в виде такого репозитория: https://github.com/HofmeisterAn/dotnet-testcontainers
✅ Вы только посмотрите, как это работает:
using System.Threading.Tasks;
using DotNet.Testcontainers.Containers.Builders;
using DotNet.Testcontainers.Containers.Configurations.Databases;
using DotNet.Testcontainers.Containers.Modules.Abstractions;
using DotNet.Testcontainers.Containers.Modules.Databases;
using MySql.Data.MySqlClient;
using NUnit.Framework;
namespace TryTestContainers;
public sealed class UnitTest1
{
private readonly TestcontainerDatabase _testcontainers = new TestcontainersBuilder<MySqlTestcontainer>()
.WithDatabase(new MySqlTestcontainerConfiguration
{
Database = "db",
Username = "mysql",
Password = "mysql",
})
.Build();
[SetUp]
public async Task SetUp()
{
await _testcontainers.StartAsync();
}
[TearDown]
public async Task TearDown()
{
await _testcontainers.DisposeAsync().AsTask();
}
[Test]
public void TestMethod()
{
using MySqlConnection connection = new MySqlConnection(_testcontainers.ConnectionString);
using var command = new MySqlCommand();
connection.Open();
command.Connection = connection;
command.CommandText = "SELECT 1";
command.ExecuteReader();
}
}
Если вы, как и я, пропускаете большие блоки кода при чтении (да-да, ты не один такой ленивый, нас как минимум двое 👬), то вот вам текстовое описание происходящего:
1. В переменной _testcontainers мы создаем конфигурацию контейнера, также как мы это обычно делаем в docker-compose.yaml
2. В методе SetUp мы запускаем эти контейнеры. Они запускаются в вашем локальном Docker
3. В методе TestMethod мы подключаемся к базе данных и делаем запрос.
4. В методе TearDown мы их гасим, после всех тестов
Звучит достойно! Но еще более достойно звучит тот факт, что таким же макаром вы можете поднимать RabbitMq, Kafka и еще всякие штуки!
🅰️Итого: Если вам хочется делать тесты на уровне классов, которые ходят в инфраструктурные сервисы, вы можете использовать эту штуку. Но кажется надо посмотреть, как такие тесты поднимать в Github Actions? Как запускать их в параллель? Я попробую ответить на эти вопросы завтра, а вам пореомендую не сцать и тоже попробовать эту штуку!
P.S. Естественно, я въебал звезду на гитхабе этому проекту. И ты тоже не сиди, пойди и въеби звезду! У проекта уже 994 ⭐, так что это серьезно!