Testcontainers چیست؟
کتابخانهای که در زمان اجرای تست، وابستگیهای واقعی (دیتابیس، Redis، RabbitMQ) را داخل کانتینر Docker موقت بالا میآورد و بعد از تست خودکار حذف میکند.
چرا مهم است؟
Integration Testهایی که به SQLite/In-Memory Provider وابستهاند، رفتار واقعی SQL Server یا Postgres را دقیقاً شبیهسازی نمیکنند؛ Testcontainers یک نمونه واقعی و ایزوله از همان دیتابیس Production میسازد، بدون نصب دائمی روی ماشین توسعه یا CI.
تعریف
Testcontainers کتابخانهای است که قبل از اجرای Integration Test، یک کانتینر Docker واقعی (مثلاً SQL Server، PostgreSQL، Redis) بالا میآورد، Connection String آن را در اختیار تست میگذارد و بعد از پایان، کانتینر را خودکار حذف میکند.
مثال
public class OrdersRepositoryTests : IAsyncLifetime
{
private readonly MsSqlContainer _sqlContainer = new MsSqlBuilder().Build();
public async Task InitializeAsync() => await _sqlContainer.StartAsync();
public async Task DisposeAsync() => await _sqlContainer.DisposeAsync();
[Fact]
public async Task AddOrder_PersistsToDatabase()
{
using var connection = new SqlConnection(_sqlContainer.GetConnectionString());
// ... اجرای مایگریشن و تست واقعی روی دیتابیس
}
}
چرا بهتر از In-Memory Provider است
Provider حافظهای EF Core محدودیتها و رفتار SQL واقعی (Constraint، Transaction، نوع داده) را کامل شبیهسازی نمیکند؛ باگی که فقط روی SQL Server واقعی رخ میدهد، با In-Memory Provider هرگز دیده نمیشود.
اشتباه رایج
❌ بالا نگهداشتن یک کانتینر مشترک بین همه تستها بدون ایزولهسازی داده — تستها روی هم اثر میگذارند و نتیجه به ترتیب اجرا وابسته میشود؛ بهتر است هر مجموعه تست دیتابیس خودش را داشته باشد یا هر تست Transaction را Rollback کند.
منبع و مطالعه بیشتر
خلاصه
Testcontainers برای Integration Test یک نمونه واقعی از دیتابیس/سرویس داخل Docker بالا میآورد و بعد خودکار حذف میکند. این کار دقیقتر از In-Memory Provider است چون رفتار واقعی SQL را شبیهسازی میکند. مراقب اشتراکگذاری کانتینر بین تستها بدون ایزولهسازی داده باشید. مرجع کامل: مستندات رسمی Testcontainers for .NET.
