تخطَّ إلى المحتوى

synctest.Test

تشغيل اختبار داخل فقاعة زمن وهمي synctest.Test

synctest.Test يشغّل دالة اختبار داخل فقاعة (bubble) بساعة وهمية تتقدّم فورًا لا بالوقت الحقيقي — فيصبح اختبار كود يستخدم time.Sleep أو مُهلًا زمنية سريعًا وحتميًّا بدل بطيء وغير مستقرّ.

testing/synctest مستقرّة (GA) منذ Go 1.25، بعد أن كانت تجريبية خلف GOEXPERIMENT=synctest بـ Go 1.24. synctest.Test يشغّل الدالة الممرَّرة داخل فقاعة معزولة بساعة وهمية تبدأ من لحظة ثابتة. الساعة تتقدّم فورًا فقط عندما تصل كل goroutine داخل الفقاعة لحالة حجب دائم: إرسال أو استقبال قناة، sync.WaitGroup.Wait، أو time.Sleep. عمليات مثل قفل sync.Mutex أو I/O شبكة أو نداءات نظام لا تُعتبر حجبًا دائمًا، فتبقى انتظارًا حقيقيًا كالمعتاد ولا تُقدّم الساعة.

لو وصلت كل الـ goroutines لحجب بلا أي طريق للتقدّم (جمود حقيقي)، Test تفزع (panic) بدل تعليق الاختبار للأبد.

الصياغة

func Test(t *testing.T, f func(t *testing.T))

📄 مثال

func TestRetryWithBackoff(t *testing.T) {
  synctest.Test(t, func(t *testing.T) {
    start := time.Now()
    err := RetryWithBackoff(3, func() error { return errors.New("فشل") })
    if err == nil {
      t.Fatal("توقّعت فشلًا بعد كل المحاولات")
    }
    t.Log(time.Since(start))   // يمرّ زمن المحاولات المتكرّرة فورًا، بلا انتظار حقيقي
  })
}

أهم النقاط

العنصرالوظيفة
synctest.Test(t, f)يشغّل f داخل فقاعة معزولة بساعة وهمية تبدأ من لحظة ثابتة
الحجب الدائمإرسال/استقبال قناة، WaitGroup.Wait، time.Sleep — تسمح للساعة الوهمية بالتقدّم فورًا
الحجب غير الدائمقفل mutex، I/O شبكة، نداءات نظام — لا تُقدّم الساعة، فتبقى انتظارًا حقيقيًا

💡 نصائح عملية

  • اختبر منطق المهل الزمنية وإعادة المحاولة (retry/backoff) بـ synctest بدل time.Sleep حقيقي — الاختبار يصبح فوريًا وحتميًّا بلا فليكي (flaky)
  • لا تستخدم شبكة حقيقية أو قفل mutex كنقطة انتظار وحيدة داخل الفقاعة — لن تتقدّم الساعة، وقد يعلّق الاختبار

⚠️ أخطاء شائعة

  • افتراض أن أي حجب داخل الفقاعة يُقدّم الساعة — فقط الحجب الدائم (channels، WaitGroup، Sleep) يفعل ذلك؛ حجب على mutex أو شبكة يبقى انتظارًا حقيقيًا
  • استدعاء t.Run أو t.Parallel داخل دالة الاختبار الممرَّرة لـ synctest.Test — غير مسموح ويؤدي لخطأ

خصائص ذات صلة

🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار GO الكامل بالعربي.