TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 550 subscribers
Post #429 177
💡 بهترین شیوه‌ها برای تست یکپارچه‌سازی با Testcontainers در NET.

تست‌های یکپارچه‌سازی با Testcontainers قدرتمند هستند، اما اگر از الگوهای صحیح پیروی نکنید، به سرعت می‌توانند به یک کابوس نگهداری تبدیل شوند. 😫

من تیم‌هایی را دیده‌ام که با تست‌های شکننده (flaky)، مجموعه تست‌های کند، و سردردهای پیکربندی دست و پنجه نرم می‌کنند که با رعایت شیوه‌های بهتر از همان ابتدا، قابل اجتناب بودند.

امروز الگوهایی را به شما نشان خواهم داد که تست‌های Testcontainers را قابل اعتماد، سریع و آسان برای نگهداری می‌کنند.

Testcontainers چگونه تست یکپارچه‌سازی را تغییر می‌دهد؟

تست‌های یکپارچه‌سازی سنتی اغلب به دیتابیس‌های تست اشتراکی یا جایگزین‌های درون-حافظه‌ای (in-memory) تکیه می‌کنند که با رفتار محیط پروداکشن مطابقت ندارند. شما یا با آلودگی تست بین اجراها سر و کار دارید یا واقع‌گرایی را فدای سرعت می‌کنید.

تست کانتینر‌ها این مشکل را با بالا آوردن کانتینرهای واقعی Docker 🐳 برای وابستگی‌های شما حل می‌کند. تست‌های شما در برابر PostgreSQL، Redis یا هر سرویس دیگری که در پروداکشن استفاده می‌کنید، اجرا می‌شوند. وقتی تست‌ها کامل شدند، کانتینرها از بین می‌روند و هر بار یک محیط تمیز در اختیار شما قرار می‌دهند.

این جادو 🪄 از طریق API داکر اتفاق می‌افتد. Testcontainers کل چرخه حیات را مدیریت می‌کند: دریافت ایمیج‌ها، شروع کانتینرها، انتظار برای آماده شدن، و پاک‌سازی. کد تست شما فقط باید بداند چگونه به آن‌ها متصل شود.

پیش‌نیازها 📦

اول، مطمئن شوید که پکیج‌های لازم را دارید:
Install-Package Microsoft.AspNetCore.Mvc.Testing
Install-Package Testcontainers.PostgreSql
Install-Package Testcontainers.Redis

ساختن کانتینرهای تست 🏗

در اینجا نحوه راه‌اندازی کانتینرهای خود با پیکربندی مناسب آمده است:
PostgreSqlContainer _postgresContainer = new PostgreSqlBuilder()
.WithImage("postgres:17")
.WithDatabase("devhabit")
.WithUsername("postgres")
.WithPassword("postgres")
.Build();

RedisContainer _redisContainer = new RedisBuilder()
.WithImage("redis:latest")
.Build();

برای شروع و توقف تمیز کانتینرها در سراسر مجموعه تست خود، IAsyncLifetime را در WebApplicationFactory خود پیاده‌سازی کنید:
public sealed class IntegrationTestWebAppFactory : WebApplicationFactory<Program>, IAsyncLifetime
{
// ... تعریف کانتینرها ...

public async Task InitializeAsync()
{
await _postgresContainer.StartAsync();
await _redisContainer.StartAsync();
// وابستگی‌های دیگر را اینجا شروع کنید
}

public async Task DisposeAsync()
{
await _postgresContainer.StopAsync();
await _redisContainer.StopAsync();
}
}

این کار تضمین می‌کند که کانتینرها قبل از اجرای تست‌ها آماده و پس از آن پاک‌سازی شوند. این یعنی هیچ وضعیت باقیمانده از داکر یا شرایط رقابتی (race conditions) وجود نخواهد داشت.

📌 نکته: نسخه‌های ایمیج خود را پین کنید (مانند postgres:17) تا از غافلگیری‌های ناشی از تغییرات بالادستی جلوگیری کنید.

انتقال پیکربندی به اپلیکیشن شما ✅

بزرگترین اشتباهی که می‌بینم، هاردکد کردن connection stringها است. Testcontainers پورت‌های داینامیک اختصاص می‌دهد. هیچ چیز را هاردکد نکنید.

در عوض، مقادیر را از طریق WebApplicationFactory.ConfigureWebHost تزریق کنید:
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseSetting("ConnectionStrings:Database", _postgresContainer.GetConnectionString());
builder.UseSetting("ConnectionStrings:Redis", _redisContainer.GetConnectionString());
}


📍نکته کلیدی استفاده از متد UseSetting برای انتقال داینامیک connection stringها است. این کار همچنین از هرگونه شرایط رقابتی یا تداخل با تست‌های دیگری که ممکن است به صورت موازی اجرا شوند، جلوگیری می‌کند.

اشتراک‌گذاری تنظیمات پرهزینه با xUnit Collection Fixtures
💡فیکسچر تست (test fixture) چیست؟

یک فیکسچر یک زمینه اشتراکی برای تست‌های شماست که به شما اجازه می‌دهد منابع پرهزینه مانند دیتابیس‌ها یا message brokerها را یک بار راه‌اندازی کرده و در چندین تست از آن‌ها استفاده مجدد کنید.

اینجاست که اکثر تیم‌ها دچار مشکل می‌شوند. انتخاب بین class و collection fixtures بر عملکرد و ایزوله‌سازی تست تأثیر می‌گذارد.
More from @csharpgeeks
  1. Sep 22, 2026یه مدتی قراره از دنیای NET. فاصله بگیرم، چون وقتشه برم سربازی. راستش نمیدونم این مدت رو چج…
  2. Sep 20, 2026🔥 حالا مشکل اصلی: Alert Storm فرض کن Database از دسترس خارج شده. ۱۰۰ Pod داری. هر Pod می‌…
  3. Sep 20, 2026🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ فرض کن ساعت ۳ صبح است. سیستم شما با…
  4. Sep 19, 2026#Engineering_Leadership تصمیم نگرفتن هم یک تصمیم است یه چیز عجیب توی تیم‌های مهندسی: گاهی…
  5. Sep 19, 2026☑ چک‌لیست آماده‌سازی تیم، فرایندها و زیرساخت برای توسعه با AI توجه: هیچ چک‌لیستی جهان‌شمول…
  6. Sep 19, 2026📌پایان یک انتظار طولانی: اعتبارسنجی ناهمگام (Async Validation) در NET 11.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →