خط لوله CI/CD من ۳ ماه بود که با موفقیت اجرا میشد — تا اینکه لاگها را خواندم
تیکهای سبز حس خوبی دارند. تمام pull requestها با موفقیت انجام شده بودند. تمام deployها درست کار میکردند.
سپس کاربری گزارش داد که یک قابلیت خراب شده است. آن قابلیت هفتهها بود که از کار افتاده بود.
لاگهای خط لوله را باز کردم. بیلدهای موفق ما داشتند به ما دروغ میگفتند.
فرآیند ما بینقص به نظر میرسید:
- Linting
- Unit tests
- Integration tests
- Build
- Deploy
هر مرحله برای ماهها نرخ موفقیت ۱۰۰٪ داشت.
دکمه export با کلیک کردن هیچ کاری انجام نمیداد. هیچ خطایی هم ظاهر نمیشد. من ریشهی مشکل را تا تغییری در ۱۱ هفته پیش دنبال کردم. خط لوله با موفقیت اجرا شده بود. code review تایید شده بود. آن قابلیت از همان ابتدا خراب بود.
مشکل از کد ما نبود. مشکل از کد تست ما بود.
تستهای integration ما برای همه چیز از mock استفاده میکردند. ما کل سرویس export را mock کرده بودیم. تست به جای کد واقعی، mock را چک میکرد. mock همیشه وضعیت success را برمیگرداند.
ما در تلهی over-mocking گرفتار شده بودیم:
- Unit tests: برای ایزوله کردن واحد، همه چیز را mock کردیم. این اشکالی ندارد.
- Integration tests: برای سرعت، همه چیز را mock کردیم. این یک اشتباه است.
- E2E tests: این جریان (flow) خاص را نادیده گرفته بودیم.
تستهای integration ما فقط unit testهای پرهزینه بودند. آنها فقط تایید میکردند که mockهای ما درست کار میکنند، نه اینکه کد ما درست کار میکند.
برای رفع این مشکل، سه تغییر ایجاد کردم:
۱. استفاده از mock را به unit testها محدود کنید. تستهای integration باید به دیتابیسها، APIها و سیستمهای فایل واقعی متصل شوند. اگر تست کند است، آن را با یک mock پنهان نکنید. از آن سرعت به عنوان سیگنالی برای بهینهسازی استفاده کنید.
۲. تستهای contract اضافه کنید. این تستها تضمین میکنند که mockهای شما با رفتار واقعی سرویس مطابقت دارند. اگر یک mock دادهای را برگرداند که یک سرویس واقعی نمیتواند برگرداند، تست contract با شکست مواجه میشود.
۳. پوشش (coverage) واقعی را پیگیری کنید. ما دیگر به نرخ موفقیت ساده نگاه نمیکردیم. به این نگاه میکردیم که تستها واقعاً چه بخشهایی را اجرا کردهاند. اعداد coverage ما از ۹۴٪ به ۶۷٪ کاهش یافت. این صادقانهترین معیار ما بود.
سبز بودن خط لوله به این معنا نیست که کد شما کار میکند؛ بلکه به این معناست که تستهای شما با موفقیت انجام شدهاند. این دو موضوع با هم متفاوت هستند.
خطرناکترین باگها آنهایی هستند که خط لوله شما میگوید مشکلی ندارند.
این سوالات را از خود بپرسید:
- آیا تستهای من باگها را پیدا میکنند یا فقط صحت mockها را تایید میکنند؟
- آیا تستهای integration من واقعاً یکپارچگی (integration) را بررسی میکنند؟
- اگر تمام mockها را حذف کنم، چند تست همچنان با موفقیت اجرا میشوند؟
- آیا دارم coverage را اندازهگیری میکنم یا میزان اطمینان (confidence) را؟
خط لولهای که هرگز با شکست مواجه نمیشود، قابل اعتماد نیست؛ بلکه تستنشده است.
Source: https://dev.to/kollittle/my-cicd-pipeline-passed-for-3-months-then-i-read-the-logs-4mbj
