مقدمه
الگوی Arrange-Act-Assert (AAA) امروزه تقریباً به یک استاندارد در تستنویسی تبدیل شده است. این الگو پیشنهاد میدهد که متد تست خود را به سه بخش تقسیم کنید:
- Arrange: آمادهسازی مقدمات تست
- Act: اجرای عملیات موردنظر
- Assert: بررسی خروجی یا تأیید انتظارات
هر بخش تنها باید مسئول همان وظیفهای باشد که نام آن نشان میدهد.
بخشها
در بخش Arrange تنها باید کدی نوشته شود که برای راهاندازی شرایط تست موردنیاز است. در این قسمت معمولاً:
نمونههای موردنیاز ساخته میشوند؛
آبجکتهای mock مقداردهی یا تنظیم میشوند؛
و در صورت لزوم، انتظارات از رفتار آنها مشخص میگردد.
در بخش Act باید تنها متد مورد تست فراخوانی شود.
در نهایت، در Assert بررسی میکنیم که آیا نتیجهی بهدستآمده مطابق با انتظار ما بوده یا خیر (اعم از بررسی خروجیها یا تعاملهای بین آبجکتها).
نمونه کد GO Lang
func TestUserService_Register_SavesUser(t *testing.T) {
// Arrange
mockRepo := new(MockUserRepository)
user := User{Name: "Alice"}
mockRepo.On("Save", user).Return(nil)
service := UserService{repo: mockRepo}
// Act
err := service.Register(user)
// Assert
assert.NoError(t, err)
mockRepo.AssertExpectations(t)
}
توضیح ساختار AAA در این تست
Arrange
ساخت mock از UserRepository و تعریف رفتار مورد انتظار (On("Save", user).Return(nil))
Act
اجرای متد Register روی UserService
Assert
بررسی اینکه Save واقعاً صدا زده شده و خطایی برگشت داده نشده
توجه کنید که در اینجا بخشهای مختلف با کامنتهایی مانند // Arrange، // Act و // Assert مشخص شدهاند. اما آیا واقعاً لازم است که در همه تستها از این نوع کامنتها استفاده شود؟
چالش: آیا کامنتها واقعاً ضروریاند؟
پاسخ این سؤال بستگی به سطح وسواس توسعهدهنده دارد!
اگر به این اصل معتقدید که کد تمیز باید خودش توضیحدهنده خودش باشد—مثل خواندن یک متن انگلیسی یا هر زبان دیگری—آنگاه اضافه کردن کامنتهایی که دقیقاً بگویند «الان داریم چه کاری میکنیم»، کمی بیمورد یا حتی مضحک به نظر میرسد.
در متن نوشتاری، هر پاراگراف بهخوبی خودش را معرفی میکند. اگر این کار در متن نوشتاری بیمعناست، چرا در کد انجام دهیم؟
چرا استفاده از این کامنتها ایدهی خوبی نیست؟
کد تست نیز باید مانند کد پروداکشن، از اصول کدنویسی خوب تبعیت کند. از جمله:
رعایت اصولی مانند:
- DRY (تکرار نکن)
- YAGNI (چیزی رو که نیاز نداری پیادهسازی نکن)
- SRP (اصل تکوظیفگی)
- KISS (ساده نگهدار)
و یا پرهیز از مقادیر جادویی (Magic Numbers) و دیگر TestSmell ها
استفاده مداوم از کامنتهای بخشبندی ممکن است باعث ایجاد کد شلوغ و تکراری شود که در بلندمدت خوانایی آن کاهش مییابد.
اما چرا برخی افراد این کار را انجام میدهند؟
هنگامی که فردی در حال یادگیری یک تکنیک جدید است، استفاده از الگوهای کمکی و ساختارهای از پیشتعریفشده میتواند مفید باشد.
مثل زمانی که در حال یادگیری زبان خارجی هستید و معلم به شما الگوهای جملات آماده میدهد که تنها باید جاهای خالی را پر کنید.
در تستنویسی هم وقتی یک نفر تازهکار است، کامنتگذاری به سبک AAA کمک میکند تا مطمئن شود تست به شکل درستی نوشته شده.
اما وقتی این مهارت جا افتاد و تبدیل به بخش طبیعی از تفکر شد، دیگر نیازی به این ساختار کمکی نیست.
نکات پایانی
کد تست، همانند کد پروداکشن، باید تمیز، ساده و خودتوضیحدهنده باشد. اضافه کردن توضیحاتی که قرار است فقط بخش بعدی را معرفی کنند، معمولاً تنها شلوغی اضافه ایجاد میکند.
با رعایت اصول ساختاری مناسب و استفاده از نامگذاری درست برای متدهای تست، میتوان بدون کامنت هم بخشهای Arrange، Act و Assert را از هم تمایز داد—و این دقیقاً همان هدف اصلی AAA است.