تست رگرسیون (Regression Testing) یعنی اطمینان از اینکه یک تغییر تازه، بخش‌های سالم قبلی محصول را خراب نکرده است. هر رفع باگ، هر قابلیت جدید و حتی یک به‌روزرسانی کتابخانه می‌تواند رفتار جای دیگری از نرم‌افزار را عوض کند. در این راهنما می‌بینیم تست رگرسیون چه زمانی لازم است، دامنه‌اش را چطور انتخاب کنیم و چطور آن را قابل نگهداری نگه داریم.

اگر تازه با مفاهیم پایه آشنا می‌شوید، پیشنهاد می‌کنیم اول راهنمای تست نرم‌افزار چیست را بخوانید.

تست رگرسیون چیست و چه مسئله‌ای را حل می‌کند

رگرسیون یعنی «پسرفت». باگ رگرسیون یعنی قابلیتی که قبلاً درست کار می‌کرد، حالا دیگر کار نمی‌کند. تست رگرسیون مجموعه‌ای از تست‌های قبلاً پاس‌شده است که بعد از هر تغییر دوباره اجرا می‌شوند.

هدف اصلی، پیدا کردن اثر جانبی تغییر است. توسعه‌دهنده معمولاً همان بخشی را که تغییر داده بررسی می‌کند. اما وابستگی‌های پنهان همیشه دیده نمی‌شوند. یک تغییر کوچک در فرمول تخفیف ممکن است روی فاکتور، گزارش مالی و ایمیل تأیید سفارش هم اثر بگذارد.

تفاوت تست رگرسیون با تست مجدد

این دو مفهوم اغلب با هم اشتباه گرفته می‌شوند:

  • تست مجدد (Retest): همان تستی که شکست خورده بود، بعد از رفع باگ دوباره اجرا می‌شود. هدف، تأیید رفع همان باگ است.
  • تست رگرسیون: تست‌های مرتبط و گاهی کل محصول اجرا می‌شوند. هدف، اطمینان از سالم ماندن بقیه بخش‌هاست.

ترتیب منطقی معمولاً این است: اول تست مجدد، بعد رگرسیون. اگر باگ اصلاً رفع نشده باشد، اجرای رگرسیون گسترده فقط وقت تیم را می‌گیرد.

جایگاه رگرسیون در میان انواع تست

تست رگرسیون یک سطح تست مستقل نیست. می‌تواند در سطح تست واحد، یکپارچه‌سازی یا سیستم انجام شود. در مقاله انواع تست نرم‌افزار این سطوح را با جزئیات بیشتری مرور کرده‌ایم. تعریف کوتاه اصطلاح را هم در واژه‌نامه: تست رگرسیون ببینید.

چرا باگ‌های رگرسیون به وجود می‌آیند

شناخت علت‌ها کمک می‌کند تست‌ها را هدفمندتر انتخاب کنید. رایج‌ترین دلایل این‌ها هستند:

  • کد مشترک: یک تابع یا کامپوننت در چند صفحه استفاده می‌شود و تغییرش همه را تحت تأثیر قرار می‌دهد.
  • تغییر وابستگی‌ها: به‌روزرسانی فریم‌ورک، کتابخانه یا نسخه پایگاه داده رفتار سیستم را عوض می‌کند.
  • تغییر پیکربندی: تنظیمات سرور، متغیرهای محیطی یا فلگ‌های قابلیت (Feature Flag) جابه‌جا می‌شوند.
  • ادغام شاخه‌ها: تعارض‌های ادغام با عجله حل می‌شوند و بخشی از منطق از دست می‌رود.
  • تغییر ساختار داده: مهاجرت پایگاه داده روی داده‌های قدیمی رفتار متفاوتی نشان می‌دهد.
  • رفع باگ عجولانه: اصلاح یک حالت خاص، حالت‌های دیگر را می‌شکند.

چه زمانی تست رگرسیون اجرا شود

پاسخ کوتاه: هر بار که کد، پیکربندی یا محیط تغییر می‌کند. اما دامنه اجرا در هر موقعیت فرق دارد.

بعد از رفع باگ

بعد از تست مجدد، تست‌های ناحیه اطراف باگ را اجرا کنید. اگر باگ در ماژول پرداخت بود، سناریوهای اصلی پرداخت و بازگشت وجه را دوباره بررسی کنید. برای باگ‌های مهم، همین‌جا یک تست‌کیس رگرسیون دائمی هم اضافه کنید.

در هر بیلد یا ادغام در شاخه اصلی

در این مرحله یک مجموعه کوچک و سریع کافی است. معمولاً همان تست دود و چند تست خودکار حیاتی. هدف بازخورد سریع به توسعه‌دهنده است، نه پوشش کامل.

پیش از انتشار

قبل از هر انتشار، رگرسیون گسترده‌تری اجرا می‌شود. دامنه آن به ریسک تغییرات همان نسخه بستگی دارد. برای انتشارهای بزرگ یا نسخه‌هایی که ماژول‌های هسته را تغییر داده‌اند، رگرسیون کامل منطقی است.

بعد از تغییر زیرساخت

مهاجرت سرور، تغییر نسخه سیستم‌عامل یا جابه‌جایی سرویس ابری هم رگرسیون لازم دارد. حتی اگر یک خط کد تغییر نکرده باشد، رفتار محیط ممکن است عوض شده باشد.

بعد از رفع فوری در محیط عملیاتی

رفع فوری (Hotfix) معمولاً زیر فشار زمان انجام می‌شود. یک فهرست رگرسیون کوتاه و هدفمند برای این حالت از قبل آماده داشته باشید. این فهرست باید در کمتر از یک ساعت قابل اجرا باشد.

راهبردهای انتخاب دامنه رگرسیون

اجرای همه تست‌ها در هر بار معمولاً ممکن نیست. تیم‌ها بسته به زمان و ریسک یکی از این راهبردها را انتخاب می‌کنند:

راهبرد چه چیزی اجرا می‌شود مناسب برای نکته اجرایی
رگرسیون کامل همه تست‌های مجموعه رگرسیون انتشار بزرگ، تغییر زیرساخت زمان‌بر است؛ بهتر است بخش بزرگی از آن خودکار باشد
رگرسیون انتخابی تست‌های ماژول‌های تغییرکرده و وابسته به آن‌ها انتشارهای معمول به شناخت دقیق وابستگی‌ها نیاز دارد
رگرسیون مبتنی بر ریسک تست‌های با اولویت و ریسک بالا زمان محدود، رفع فوری فهرست اولویت باید مرتب به‌روز شود
رگرسیون اصلاحی تست‌های موجود بدون تغییر تغییرات داخلی بدون تغییر نیازمندی ساده‌ترین حالت است
رگرسیون پیشرونده تست‌های به‌روزشده برای رفتار جدید تغییر در نیازمندی‌ها تست‌کیس‌های قدیمی باید پیش از اجرا اصلاح شوند

بیشتر تیم‌ها ترکیبی از این راهبردها را به کار می‌برند. مثلاً در هر بیلد رگرسیون مبتنی بر ریسک و قبل از انتشار رگرسیون انتخابی. رگرسیون کامل هم برای نسخه‌های بزرگ یا دوره‌های مشخص کنار گذاشته می‌شود.

تحلیل اثر تغییر

پایه رگرسیون انتخابی، تحلیل اثر تغییر (Impact Analysis) است. قبل از اجرا با توسعه‌دهنده گفتگو کنید. بپرسید کدام فایل‌ها، سرویس‌ها و جدول‌ها تغییر کرده‌اند. بعد ببینید چه قابلیت‌هایی از آن‌ها استفاده می‌کنند. یک ماتریس ردیابی نیازمندی به‌روز این تحلیل را خیلی سریع‌تر می‌کند.

انتخاب و اولویت‌بندی تست‌کیس‌ها

کیفیت رگرسیون به کیفیت انتخاب تست‌ها وابسته است. این معیارها کمک می‌کنند:

  1. مسیرهای حیاتی کسب‌وکار: ورود کاربر، ثبت سفارش، پرداخت و هر جریانی که توقفش مستقیم به درآمد یا اعتماد آسیب می‌زند.
  2. نواحی پرتغییر: ماژول‌هایی که در چند انتشار اخیر زیاد تغییر کرده‌اند.
  3. سابقه باگ: بخش‌هایی که قبلاً باگ رگرسیون داشته‌اند.
  4. یکپارچگی‌ها: نقاط اتصال به سرویس‌های بیرونی مثل درگاه پرداخت یا سامانه پیامک.
  5. قابلیت‌های پراستفاده: صفحه‌ها و جریان‌هایی که بیشترین کاربر را دارند.
  6. الزامات قانونی و امنیتی: بخش‌هایی که خطا در آن‌ها پیامد حقوقی یا امنیتی دارد.

برچسب‌گذاری تست‌کیس‌ها

برای انتخاب سریع، تست‌کیس‌ها را برچسب بزنید. دو فیلد معمولاً کافی است: اولویت و نوع. مثلاً اولویت «بحرانی» و نوع «رگرسیون». با این کار ساختن یک اجرای رگرسیون هدفمند چند دقیقه طول می‌کشد، نه چند ساعت.

یک الگوی ساده برای سطح‌بندی:

  • سطح ۱: مسیرهای حیاتی؛ در هر بیلد اجرا می‌شوند.
  • سطح ۲: قابلیت‌های مهم؛ قبل از هر انتشار اجرا می‌شوند.
  • سطح ۳: بقیه قابلیت‌ها؛ در رگرسیون کامل یا به‌صورت چرخشی اجرا می‌شوند.

پاک‌سازی تست‌های کم‌ارزش

مجموعه رگرسیون با گذشت زمان بزرگ می‌شود. تست‌های تکراری، تست قابلیت‌های حذف‌شده و تست‌هایی که مراحلشان دیگر معتبر نیست را مرور کنید. حذف یا ادغام آن‌ها سرعت اجرا را بالا می‌برد. البته تستی که تا حالا باگی پیدا نکرده لزوماً کم‌ارزش نیست. اگر ناحیه حیاتی را پوشش می‌دهد، نگهش دارید.

ساختن و نگهداری مجموعه رگرسیون

مجموعه رگرسیون یک سند زنده است. اگر نگهداری نشود، به‌سرعت از محصول عقب می‌افتد و اعتماد تیم به نتیجه‌هایش کم می‌شود.

از کجا شروع کنیم

  • از تست‌کیس‌های موجود برای قابلیت‌های پایدار شروع کنید.
  • برای هر باگ مهم رفع‌شده، یک تست‌کیس رگرسیون اضافه کنید.
  • تست‌ها را بر اساس ماژول یا جریان کاربری گروه‌بندی کنید.
  • مراحل را طوری بنویسید که فرد دیگری بدون توضیح شفاهی بتواند اجرا کند.
  • داده تست لازم برای هر تست را مشخص کنید.

برای نوشتن تست‌کیس‌های دقیق و قابل تکرار، راهنمای نوشتن تست‌کیس را ببینید.

چرخه به‌روزرسانی

با هر تغییر نیازمندی، تست‌کیس‌های مرتبط را اصلاح کنید. بهتر است این کار بخشی از تعریف «انجام‌شده» (Definition of Done) باشد. در غیر این صورت، تسترها هنگام اجرا با مراحل قدیمی روبه‌رو می‌شوند و نتیجه‌ها قابل اعتماد نیستند.

یک مرور دوره‌ای هم مفید است. مثلاً هر سه ماه یک بار، مالک هر ماژول تست‌های آن را بازبینی کند.

مستندسازی دامنه در طرح تست

اینکه چه زمانی کدام سطح رگرسیون اجرا می‌شود باید در طرح تست نوشته شود. معیارهای ورود و خروج رگرسیون هم همان‌جا تعریف می‌شوند. این کار تصمیم‌گیری زیر فشار زمان را ساده می‌کند.

نقش اتوماسیون در تست رگرسیون

تست رگرسیون بهترین نامزد اتوماسیون است. تست‌ها تکراری‌اند، نتیجه مورد انتظار روشن است و بارها اجرا می‌شوند.

چه چیزی را خودکار کنیم

  • تست‌های پایدار با مراحل ثابت
  • سناریوهای داده‌محور با ورودی‌های زیاد
  • بررسی‌های API و منطق کسب‌وکار
  • جریان‌های حیاتی که در هر بیلد باید بررسی شوند

چه چیزی دستی بماند

  • بخش‌هایی که رابط کاربری‌شان مدام تغییر می‌کند
  • بررسی‌های ظاهری و تجربه کاربری
  • سناریوهایی که یک بار یا به‌ندرت اجرا می‌شوند

مراقب تست‌های ناپایدار باشید

یک مشکل رایج در رگرسیون خودکار، تست ناپایدار است. تستی که بدون تغییر کد گاهی پاس و گاهی شکست می‌خورد، اعتماد تیم را کم می‌کند. این تست‌ها را قرنطینه کنید، علتشان را پیدا کنید و بعد به مجموعه برگردانید.

برای تصمیم درباره شروع و مسیر اتوماسیون، مقاله اتوماسیون تست نرم‌افزار را بخوانید.

اجرای رگرسیون در چرخه انتشار

یک الگوی عملی برای تیم‌هایی که انتشار دوره‌ای دارند:

  1. فریز کد: بعد از پایان توسعه، تغییرات جدید متوقف می‌شود.
  2. اجرای تست دود: اطمینان از اینکه بیلد قابل تست است.
  3. تست قابلیت‌های جدید: تست‌های مخصوص تغییرات این نسخه.
  4. رگرسیون: بر اساس راهبرد انتخاب‌شده در طرح تست.
  5. تست مجدد باگ‌های رفع‌شده: همراه رگرسیون هدفمند اطراف آن‌ها.
  6. تصمیم انتشار: بر اساس نتیجه‌ها و معیارهای خروج.

برای تیم‌هایی که تحویل مداوم دارند، این مراحل در خط لوله فشرده می‌شوند. رگرسیون خودکار در هر ادغام اجرا می‌شود. رگرسیون دستی هم روی نواحی پرریسک و قابلیت‌های تازه متمرکز می‌شود.

گزارش نتیجه رگرسیون

گزارش رگرسیون باید به یک سؤال روشن پاسخ بدهد: آیا این نسخه برای انتشار آماده است. این موارد را در آن بیاورید:

  • تعداد تست‌های اجراشده از کل دامنه برنامه‌ریزی‌شده
  • تعداد تست‌های پاس، شکست‌خورده و مسدود
  • باگ‌های باز با شدت بالا و وضعیت هرکدام
  • نواحی‌ای که تست نشدند و دلیل آن
  • ریسک‌های باقی‌مانده و پیشنهاد تیم تست

سنجش اثربخشی رگرسیون

چند شاخص ساده کمک می‌کند بفهمید مجموعه رگرسیون واقعاً کار می‌کند:

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

تعریف و فرمول این شاخص‌ها را در معیارهای تست و گزارش کیفیت آورده‌ایم.

در TestRail می‌توانید تست‌کیس‌های رگرسیون را در سوئیت‌ها و بخش‌ها (Section) مرتب کنید و با فیلدهای نوع و اولویت برچسب بزنید. هنگام ساختن اجرای تست (Test Run) فقط کیس‌های منتخب را با فیلتر انتخاب می‌کنید. طرح تست (Test Plan) چند اجرا را برای پیکربندی‌های مختلف کنار هم نگه می‌دارد و مایلستون آن‌ها را به نسخه انتشار وصل می‌کند. نتیجه تست‌های خودکار هم از طریق API ثبت می‌شود و گزارش‌ها روند نتیجه‌ها را بین اجراها نشان می‌دهند. برای دیدن این قابلیت‌ها در کنار هم، صفحه امکانات TestRail را ببینید.

جمع‌بندی

تست رگرسیون از محصول در برابر اثر جانبی تغییرات محافظت می‌کند. کلید موفقیت، انتخاب هوشمندانه دامنه است، نه اجرای همه‌چیز در هر بار. مجموعه رگرسیون را با برچسب‌گذاری، مرور دوره‌ای و اتوماسیون تدریجی زنده نگه دارید. زمان اجرای هر سطح را در طرح تست مشخص کنید و نتیجه را با چند شاخص ساده بسنجید. برای مرور بقیه مفاهیم پایه، به راهنمای تست نرم‌افزار برگردید.