سفارشیسازی نحوه اجرای تستها (Customizing How Tests Run)
در این بخش، نحوه سفارشیسازی اجرای تستها (Customizing Test Execution) را بررسی میکنیم. این شامل پرچمهای تست (Test Flags) و متغیرهای محیطی (Environment Variables) میشود.
همچنین با تنظیمات تست (Test Settings) و پیکربندی تست (Test Configuration) آشنا خواهیم شد.
کنترل اینکه کدام تستها اجرا شوند
تا کنون در این کتاب، ما تستها را در یک پکیج خاص (پکیج cmd/web) به این صورت اجرا کردهایم:
$ go test ./cmd/web
اما همچنین میتوان تمام تستها را در پروژه فعلی خود با استفاده از الگوی وایلدکارد ./... اجرا کرد. در مورد ما، میتوانیم از آن برای اجرای تمام تستها در پروژه خود به این صورت استفاده کنیم:
$ go test ./... ok snippetbox.alexedwards.net/cmd/web 0.007s ? snippetbox.alexedwards.net/internal/models [no test files] ? snippetbox.alexedwards.net/internal/validator [no test files] ? snippetbox.alexedwards.net/ui [no test files]
یا در جهت دیگر، میتوان فقط تستهای خاصی را با استفاده از فلگ -run اجرا کرد. این به شما اجازه میدهد یک عبارت منظم مشخص کنید و فقط تستهایی که نامشان با عبارت منظم مطابقت دارد اجرا شوند.
برای مثال، میتوانیم انتخاب کنیم که فقط تست TestPing را به این صورت اجرا کنیم:
$ go test -v -run="^TestPing$" ./cmd/web/ === RUN TestPing --- PASS: TestPing (0.00s) PASS ok snippetbox.alexedwards.net/cmd/web 0.008s
و حتی میتوانید از فلگ -run برای محدود کردن تست به برخی زیرتستهای خاص با استفاده از فرمت {test regexp}/{sub-test regexp} استفاده کنید. برای مثال برای اجرای زیرتست UTC از تست TestHumanDate میتوانیم این کار را انجام دهیم:
$ go test -v -run="^TestHumanDate$/^UTC$" ./cmd/web
=== RUN TestHumanDate
=== RUN TestHumanDate/UTC
--- PASS: TestHumanDate (0.00s)
--- PASS: TestHumanDate/UTC (0.00s)
PASS
ok snippetbox.alexedwards.net/cmd/web 0.003s
در مقابل، میتوانید از اجرای تستهای خاصی با استفاده از فلگ -skip جلوگیری کنید. مانند فلگ -run که به تازگی بررسی کردیم، این به شما اجازه میدهد یک عبارت منظم مشخص کنید و هر تستی که نامش با عبارت منظم مطابقت دارد اجرا نخواهد شد. برای مثال، برای رد کردن تست TestHumanDate:
$ go test -v -skip="^TestHumanDate$" ./cmd/web/ === RUN TestPing --- PASS: TestPing (0.00s) === RUN TestCommonHeaders --- PASS: TestCommonHeaders (0.00s) PASS ok snippetbox.alexedwards.net/cmd/web 0.006s
کشینگ تست
شاید تا کنون متوجه شدهاید که اگر دقیقاً همان تست را دو بار اجرا کنید — بدون ایجاد هیچ تغییری در پکیجی که در حال تست آن هستید — سپس یک نسخه کششده از نتیجه تست نمایش داده میشود (که با علامت (cached) در کنار نام پکیج نشان داده میشود).
$ go test ./cmd/web ok snippetbox.alexedwards.net/cmd/web (cached)
در بیشتر موارد، کشینگ نتایج تست واقعاً مفید است (به خصوص برای کدبیسهای بزرگ) زیرا به کاهش زمان کلی اجرای تست کمک میکند. اما اگر میخواهید تستهای خود را به طور کامل اجرا کنید (و از کش اجتناب کنید) میتوانید از فلگ -count=1 استفاده کنید:
$ go test -count=1 ./cmd/web
به طور متناوب، میتوانید نتایج کششده برای تمام تستها را با استفاده از دستور go clean پاک کنید:
$ go clean -testcache
شکست سریع
همانطور که چند فصل پیش به طور مختصر اشاره کردم، وقتی از تابع t.Errorf() برای علامتگذاری یک تست به عنوان شکستخورده استفاده میکنید، باعث نمیشود که go test بلافاصله خارج شود. تمام تستهای دیگر شما (و زیرتستها) پس از یک شکست ادامه خواهند یافت.
اگر ترجیح میدهید تستها بلافاصله پس از اولین شکست متوقف شوند، میتوانید از فلگ -failfast استفاده کنید:
$ go test -failfast ./cmd/web
مهم است که توجه داشته باشید که فلگ -failfast فقط تستها را در پکیجی که شکست داشته است متوقف میکند. اگر در حال اجرای تستها در چندین پکیج هستید (برای مثال با استفاده از go test ./...)، سپس تستها در پکیجهای دیگر ادامه خواهند یافت.
تست موازی
به طور پیشفرض، دستور go test تمام تستها را به صورت سریالی اجرا میکند، یکی پس از دیگری. وقتی تعداد کمی تست دارید (مانند ما) و زمان اجرا بسیار سریع است، این کاملاً مناسب است.
اما اگر صدها یا هزاران تست داشته باشید، زمان اجرای کل میتواند به چیزی معنادار تبدیل شود. و در آن سناریو، ممکن است با اجرای تستها به صورت موازی، مقداری زمان صرفهجویی کنید.
میتوانید نشان دهید که اجرای یک تست به صورت همزمان با دیگر تستها مشکلی ندارد با فراخوانی تابع t.Parallel() در ابتدای تست. برای مثال:
func TestPing(t *testing.T) { t.Parallel() ... }
مهم است که در اینجا توجه داشته باشید که:
تستهایی که با استفاده از
t.Parallel()علامتگذاری شدهاند، به صورت موازی با — و فقط با — دیگر تستهای موازی اجرا خواهند شد.به طور پیشفرض، حداکثر تعداد تستهایی که به صورت همزمان اجرا خواهند شد، مقدار فعلی GOMAXPROCS است. میتوانید این مقدار را با تنظیم یک مقدار خاص از طریق فلگ
-parallelتغییر دهید. برای مثال:$ go test -parallel=4 ./...
همه تستها برای اجرا به صورت موازی مناسب نیستند. برای مثال، اگر یک تست یکپارچه دارید که نیاز به یک جدول پایگاه داده در یک حالت خاص دارد، نمیخواهید آن را به صورت موازی با دیگر تستهایی که همان جدول پایگاه داده را تغییر میدهند اجرا کنید.
فعالسازی آشکارساز رقابت
دستور go test شامل یک فلگ -race است که آشکارساز رقابت Go را هنگام اجرای تستها فعال میکند.
اگر کدی که در حال تست آن هستید از همزمانی استفاده میکند، یا در حال اجرای تستها به صورت موازی هستید، فعالسازی این میتواند ایده خوبی باشد تا شرایط رقابتی که در برنامه شما وجود دارد را پرچمگذاری کند. میتوانید از آن به این صورت استفاده کنید:
$ go test -race ./cmd/web/
باید بدانید که آشکارساز رقابت در مفید بودن خود محدود است... این فقط یک ابزار است که شرایط رقابتی را اگر و زمانی که در زمان اجرا در طول تست شناسایی شوند، پرچمگذاری میکند. این تحلیل استاتیک از کدبیس شما انجام نمیدهد، و یک اجرای بدون مشکل تضمین نمیکند که کد شما از شرایط رقابتی خالی است.
فعالسازی آشکارساز رقابت همچنین زمان کلی اجرای تستهای شما را افزایش خواهد داد. بنابراین اگر در حال اجرای تستها به صورت بسیار مکرر به عنوان بخشی از یک جریان کاری TDD هستید، ممکن است ترجیح دهید از فلگ -race فقط در طول اجرای تستهای پیش از تعهد استفاده کنید.
واژهنامه اصطلاحات فنی
| اصطلاح فارسی | معادل انگلیسی | توضیح |
|---|---|---|
| سفارشیسازی اجرای تستها | Customizing Test Execution | تنظیم نحوه اجرای تستها |
| پرچمهای تست | Test Flags | گزینههای خط فرمان تست |
| متغیرهای محیطی | Environment Variables | متغیرهای سیستمی |
| تنظیمات تست | Test Settings | پیکربندی اجرای تست |
| پیکربندی تست | Test Configuration | تنظیمات محیط تست |
| زمان اجرا | Runtime | زمان اجرای برنامه |
| پارامترهای تست | Test Parameters | مقادیر ورودی تست |
| گزینههای اجرا | Execution Options | تنظیمات اجرا |
| مسیر اجرا | Execution Path | مسیر پردازش تست |
| خروجی تست | Test Output | نتایج اجرای تست |