فهرست مطالب
در دنیای پویای توسعه نرمافزار، سرعت و کیفیت دو بال موفقیت محسوب میشوند. تیمهای توسعه همواره در تلاشند تا با حفظ کیفیت، سرعت تحویل محصول را افزایش دهند. یکی از کلیدیترین راهکارها برای دستیابی به این هدف، پیادهسازی فرآیندهای یکپارچهسازی و تحویل مداوم (CI/CD) به همراه تستهای خودکار است. GitLab CI، به عنوان یکی از ابزارهای قدرتمند در این حوزه، امکانات وسیعی را برای خودکارسازی فرآیند تست و ادغام آن در چرخه توسعه نرمافزار فراهم میکند. این مقاله به عنوان یک راهنمای جامع، شما را گام به گام با فرآیند ادغام تستهای خودکار در GitLab CI آشنا خواهد کرد.
چرا ادغام تستهای خودکار با GitLab CI حیاتی است؟
پیش از ورود به جزئیات فنی، درک اهمیت این موضوع ضروری است. ادغام تستهای خودکار در پایپلاین CI/CD مزایای متعددی را به همراه دارد:
- تشخیص زودهنگام خطاها: با اجرای خودکار تستها پس از هر تغییر در کد، خطاها و باگها در مراحل اولیه شناسایی شده و از انتقال آنها به مراحل بعدی و یا محیط عملیاتی جلوگیری میشود. این امر هزینههای رفع خطا را به طور قابل توجهی کاهش میدهد.
- افزایش سرعت توسعه: خودکارسازی تستها، نیاز به تست دستی مکرر را از بین برده و به توسعهدهندگان اجازه میدهد تا با اطمینان بیشتری کدنویسی کنند و بر روی توسعه ویژگیهای جدید تمرکز نمایند.
- بهبود کیفیت محصول نهایی: اجرای مداوم و خودکار مجموعه کاملی از تستها، تضمینکننده سطح بالاتری از کیفیت و پایداری برای نرمافزار است.
- بازخورد سریع: توسعهدهندگان بلافاصله پس از Push کردن تغییرات، از نتیجه تستها مطلع میشوند. این بازخورد سریع به آنها کمک میکند تا مشکلات را به سرعت شناسایی و رفع کنند.
- افزایش اعتماد به نفس تیم: دانستن اینکه مجموعهای از تستهای جامع به طور خودکار اجرا میشوند، اعتماد به نفس تیم را برای ایجاد تغییرات و ارائه نسخههای جدید افزایش میدهد.
- بهینهسازی فرآیند انتشار (Release): با اطمینان از پایداری کد از طریق تستهای خودکار، فرآیند انتشار نسخههای جدید نرمافزار سادهتر، سریعتر و با ریسک کمتری انجام میشود.
پیشنیازها برای شروع
برای دنبال کردن این راهنما، به موارد زیر نیاز خواهید داشت:
- یک حساب کاربری در GitLab (میتواند GitLab.com یا یک نمونه خودمیزبان باشد).
- یک پروژه در GitLab که میخواهید تستهای خودکار را برای آن پیکربندی کنید.
- آشنایی اولیه با مفاهیم Git و فرآیندهای CI/CD.
- دانش پایه در مورد نوع تستهایی که قصد اجرای آنها را دارید (مثلاً تست واحد، تست یکپارچهسازی).
- تستهای خودکار نوشته شده برای پروژه شما (برای مثال با استفاده از فریمورکهایی مانند JUnit برای جاوا، PyTest یا Unittest برای پایتون، Jest یا Mocha برای جاوااسکریپت و غیره).
آشنایی با مفاهیم کلیدی GitLab CI
قبل از پیکربندی، بیایید با برخی از مفاهیم اصلی در GitLab CI آشنا شویم:
.gitlab-ci.yml
: این فایل قلب تپنده GitLab CI است. یک فایل با فرمت YAML که در ریشه پروژه شما قرار میگیرد و نحوه ساخت، تست و استقرار برنامه شما را تعریف میکند.- Pipeline (پایپلاین): مجموعهای از مراحل (Stages) و کارها (Jobs) که به ترتیب خاصی اجرا میشوند. هر بار که کدی به مخزن Push میشود (یا بر اساس تریگرهای دیگر)، یک پایپلاین جدید ایجاد و اجرا میشود.
- Stages (مراحل): پایپلاینها به مراحل مختلفی تقسیم میشوند (مثلاً
build
,test
,deploy
). کارها در یک مرحله به صورت موازی اجرا میشوند (اگر منابع کافی وجود داشته باشد) و تنها در صورت موفقیت تمامی کارهای یک مرحله، مرحله بعدی آغاز میشود. - Jobs (کارها): دستورالعملهای مشخصی هستند که در یک Runner اجرا میشوند. هر کار شامل اسکریپتهایی است که باید اجرا شوند (مثلاً کامپایل کد، اجرای تستها).
- Runners (اجراکنندگان): ماشینها (فیزیکی یا مجازی) هستند که پایپلاینهای CI/CD شما را اجرا میکنند. GitLab انواع مختلفی از Runnerها را ارائه میدهد:
- Shared Runners: توسط GitLab مدیریت شده و برای تمامی پروژهها در GitLab.com در دسترس هستند.
- Specific Runners: توسط شما برای پروژههای خاصی راهاندازی و مدیریت میشوند.
- Group Runners: برای تمامی پروژههای یک گروه خاص در دسترس هستند.
- Artifacts (مصنوعات): فایلها یا دایرکتوریهایی هستند که توسط یک کار تولید میشوند و میتوانند برای استفاده در کارهای بعدی در همان پایپلاین (یا برای دانلود) ذخیره شوند. گزارشهای تست و فایلهای پوشش کد (Code Coverage) نمونههایی از مصنوعات هستند.
انواع تستهای خودکار قابل ادغام
میتوانید انواع مختلفی از تستهای خودکار را در پایپلاین GitLab CI خود ادغام کنید:
- تستهای واحد (Unit Tests): کوچکترین بخشهای کد (مانند توابع یا متدها) را به صورت مجزا تست میکنند. سرعت اجرای بالایی دارند و برای شناسایی سریع خطاها در منطق کد بسیار مفیدند.
- تستهای یکپارچهسازی (Integration Tests): تعامل بین چند جزء یا ماژول از سیستم را بررسی میکنند. هدف آنها اطمینان از صحت عملکرد اجزای مختلف در کنار یکدیگر است.
- تستهای سرتاسری (End-to-End Tests یا E2E Tests): کل جریان کاری یک برنامه را از دید کاربر نهایی شبیهسازی میکنند. این تستها پیچیدهتر و زمانبرتر هستند اما دید جامعی از عملکرد سیستم ارائه میدهند.
- تستهای عملکرد (Performance Tests): سرعت، پایداری و پاسخگویی برنامه تحت بار کاری مشخص را ارزیابی میکنند.
- تستهای امنیت (Security Tests): آسیبپذیریهای امنیتی برنامه را شناسایی میکنند.
تمرکز این مقاله بیشتر بر روی ادغام تستهای واحد و یکپارچهسازی خواهد بود، اما اصول مشابهی برای سایر انواع تستها نیز قابل اعمال است.
راهنمای گام به گام ادغام تستهای خودکار در GitLab CI
اکنون که با مفاهیم پایه آشنا شدیم، بیایید مراحل عملی ادغام تستها را بررسی کنیم.
گام ۱: آمادهسازی پروژه و تستها
اطمینان حاصل کنید که پروژه شما در GitLab موجود است و تستهای خودکار برای آن نوشته شدهاند. دستورات لازم برای اجرای این تستها از طریق خط فرمان (CLI) باید مشخص باشند. به عنوان مثال، اگر از پایتون و PyTest استفاده میکنید، دستور معمول pytest
است، یا برای یک پروژه Node.js با Jest، دستور npm test
یا yarn test
خواهد بود.
گام ۲: ایجاد فایل .gitlab-ci.yml
در ریشه پروژه خود، یک فایل جدید با نام .gitlab-ci.yml
ایجاد کنید. این فایل جایی است که شما پایپلاین CI/CD خود را تعریف خواهید کرد.
گام ۳: تعریف مراحل (Stages)
ابتدا، مراحل پایپلاین خود را تعریف کنید. یک ترتیب معمول میتواند شامل مراحل ساخت، تست و استقرار باشد.
stages:
- build
- test
- deploy # این مرحله فعلاً اختیاری است و میتوان بعداً اضافه کرد
گام ۴: ایجاد کار (Job) برای اجرای تستها
حالا یک کار جدید برای اجرای تستهای خودکار در مرحله test
تعریف میکنیم. در این مثال، فرض میکنیم که پروژه ما یک برنامه پایتون است و از pytest
برای تست استفاده میکند.
stages:
- build # ممکن است برای پروژه شما مرحله build لازم باشد
- test
# مثال کار برای یک پروژه پایتون
python_tests:
stage: test
image: python:3.9 # استفاده از یک ایمیج داکر با پایتون نسخه ۳.۹
before_script:
- pip install -r requirements.txt # نصب وابستگیها، شامل pytest
script:
- pytest --junitxml=report.xml # اجرای تستها و تولید گزارش در فرمت JUnit XML
artifacts:
when: always # همیشه مصنوعات را جمعآوری کن، حتی اگر کار شکست بخورد
reports:
junit: report.xml # مشخص کردن مسیر گزارش تست برای نمایش در GitLab UI
paths:
- report.xml # ذخیره فایل گزارش به عنوان مصنوع
# - htmlcov/ # اگر گزارش پوشش کد HTML دارید، آن را نیز اضافه کنید
توضیح بخشهای مختلف کار python_tests
:
stage: test
: مشخص میکند که این کار به مرحلهtest
تعلق دارد.image: python:3.9
: ایمیج داکری که برای اجرای این کار استفاده خواهد شد. شما باید ایمیجی را انتخاب کنید که محیط مناسب برای اجرای تستهای شما را فراهم کند (مثلاًnode:16
برای پروژههای Node.js).before_script
: دستوراتی که قبل از اجرای اسکریپت اصلی (script
) اجرا میشوند. معمولاً برای نصب وابستگیها یا آمادهسازی محیط استفاده میشود.script
: دستورات اصلی که برای اجرای تستها استفاده میشوند. در اینجا،pytest --junitxml=report.xml
تستها را اجرا کرده و نتایج را در فایلی به نامreport.xml
با فرمت JUnit ذخیره میکند. این فرمت توسط GitLab برای نمایش خلاصه تستها در رابط کاربری پشتیبانی میشود.artifacts
: برای ذخیره فایلهای تولید شده توسط کار.when: always
: این اطمینان را میدهد که گزارش تست حتی در صورت شکست تستها نیز جمعآوری و ذخیره شود.reports: junit: report.xml
: این بخش به GitLab میگوید که فایلreport.xml
حاوی نتایج تست در فرمت JUnit است. GitLab از این اطلاعات برای نمایش یکپارچه نتایج تست در صفحه Merge Request و Pipeline استفاده میکند.paths
: لیست فایلها یا دایرکتوریهایی که باید به عنوان مصنوعات ذخیره شوند.
مثال برای پروژه Node.js با Jest:
stages:
- test
node_tests:
stage: test
image: node:18 # استفاده از ایمیج داکر با Node.js نسخه ۱۸
before_script:
- npm install # یا yarn install
script:
- npm test -- --reporters=default --reporters=jest-junit # اجرای تستها و تولید گزارش JUnit
artifacts:
when: always
reports:
junit: junit.xml # مسیر پیشفرض خروجی jest-junit
paths:
- junit.xml
# - coverage/ # برای گزارش پوشش کد
در این مثال، فرض شده که jest-junit
به عنوان یک devDependency
نصب شده و در package.json
پیکربندی شده تا خروجی را در junit.xml
بنویسد.
گام ۵: Commit و Push کردن تغییرات
فایل .gitlab-ci.yml
را به مخزن Git خود اضافه، commit و push کنید:
git add .gitlab-ci.yml
git commit -m "Add GitLab CI configuration for automated testing"
git push
پس از push کردن تغییرات، GitLab به طور خودکار یک پایپلاین جدید را بر اساس پیکربندی شما در .gitlab-ci.yml
اجرا خواهد کرد.
گام ۶: مشاهده نتایج پایپلاین و تستها
به پروژه خود در GitLab بروید و از منوی سمت چپ، گزینه CI/CD > Pipelines
را انتخاب کنید. در اینجا میتوانید وضعیت پایپلاین در حال اجرا یا آخرین پایپلاین اجرا شده را مشاهده کنید.
با کلیک بر روی پایپلاین، میتوانید جزئیات مراحل و کارهای انجام شده را ببینید. اگر روی کار مربوط به تست کلیک کنید، خروجی کنسول (log) آن کار نمایش داده میشود.
همچنین، به لطف بخش artifacts:reports:junit
، نتایج تستها به صورت یکپارچه در GitLab نمایش داده میشوند. در صفحه Merge Request و همچنین در تب Tests
مربوط به پایپلاین، میتوانید خلاصهای از تستهای موفق، ناموفق و نادیده گرفته شده را مشاهده کنید.
بهترین شیوهها برای ادغام تستهای خودکار در GitLab CI
برای بهرهوری بیشتر و نگهداری آسانتر، به نکات زیر توجه کنید:
- اجرای موازی تستها: اگر مجموعه تستهای شما بزرگ است، آنها را به چند کار موازی تقسیم کنید تا زمان اجرای کلی پایپلاین کاهش یابد. GitLab CI این امکان را با استفاده از کلمه کلیدی
parallel
فراهم میکند. - بهینهسازی زمان اجرای تست: تستهای کند میتوانند سرعت بازخورد را کاهش دهند. تستهای خود را بهینه کنید و تستهای طولانیتر (مانند E2E) را در مراحل جداگانه یا با فرکانس کمتری اجرا کنید.
- استفاده از Runnerهای مناسب: برای کارهای سنگین یا نیازمند منابع خاص، از Specific Runnerها با مشخصات مناسب استفاده کنید.
- مدیریت دادههای حساس: از متغیرهای CI/CD در GitLab برای ذخیره اطلاعات حساس مانند توکنها یا کلیدهای API استفاده کنید و آنها را مستقیماً در فایل
.gitlab-ci.yml
قرار ندهید. - پوشش کد (Code Coverage): گزارشهای پوشش کد را تولید و به عنوان مصنوع ذخیره کنید. GitLab میتواند این گزارشها را تجزیه و تحلیل کرده و در رابط کاربری نمایش دهد. برای این کار، باید از ابزارهای پوشش کد مربوط به زبان برنامهنویسی خود استفاده کنید و خروجی آن را در
.gitlab-ci.yml
با استفاده ازcoverage
keyword پیکربندی نمایید.# ... بخشهای دیگر کار تست ... coverage: '/\d+\%\s*coverage/' # یک عبارت منظم برای استخراج درصد پوشش از خروجی کنسول artifacts: paths: - htmlcov/ # اگر گزارش HTML تولید میکنید - coverage.xml # اگر گزارش XML تولید میکنید reports: cobertura: coverage.xml # برای نمایش پوشش کد در GitLab UI
- کوچک و متمرکز نگه داشتن کارها: هر کار باید یک مسئولیت مشخص داشته باشد. این کار اشکالزدایی و نگهداری را سادهتر میکند.
- استفاده از Cache: برای سرعت بخشیدن به پایپلاینها، وابستگیها (مانند پکیجهای
node_modules
یاpip
) را کش کنید تا در اجراهای بعدی نیازی به دانلود مجدد آنها نباشد.# ... بخشهای دیگر کار تست ... cache: key: ${CI_COMMIT_REF_SLUG} # کلید کش میتواند بر اساس شاخه باشد paths: - .pip-cache/ # برای پایتون با pip - node_modules/ # برای Node.js
مفاهیم پیشرفتهتر (به طور خلاصه)
- اجرای شرطی کارها (Conditional Job Execution): با استفاده از
rules
یاonly/except
میتوانید تعیین کنید که یک کار تحت چه شرایطی (مثلاً فقط برای شاخههای خاص یا تگها) اجرا شود. - محیطهای تست (Test Environments): برای تستهای یکپارچهسازی یا E2E، ممکن است نیاز به راهاندازی سرویسهای جانبی (مانند پایگاه داده) داشته باشید. میتوانید از
services
در.gitlab-ci.yml
برای این منظور استفاده کنید. - Triggering Pipelines: پایپلاینها میتوانند توسط رویدادهای مختلفی (push، merge request، تگ، زمانبندی شده، API) فعال شوند.
نتیجهگیری
ادغام تستهای خودکار در GitLab CI یک سرمایهگذاری هوشمندانه برای هر تیم توسعه نرمافزار است. این فرآیند نه تنها به شناسایی زودهنگام خطاها و بهبود کیفیت محصول کمک میکند، بلکه با خودکارسازی وظایف تکراری، سرعت توسعه را نیز افزایش میدهد. با استفاده از راهنماییها و مثالهای ارائه شده در این مقاله، شما میتوانید به سادگی تستهای خودکار پروژه خود را در پایپلاین CI/CD GitLab ادغام کرده و از مزایای بیشمار آن بهرهمند شوید. به یاد داشته باشید که پیکربندی اولیه تنها قدم اول است؛ بهینهسازی مداوم پایپلاینها و مجموعه تستها برای دستیابی به بهترین نتایج ضروری خواهد بود.
سوالات متداول
بله، شما میتوانید از هر Docker image موجود در Docker Hub یا رجیستریهای خصوصی خودتان استفاده کنید. کافی است نام ایمیج را در بخش image
کار مربوطه در فایل .gitlab-ci.yml
مشخص کنید. اگر ایمیج شما در یک رجیستری خصوصی است، باید اطلاعات احراز هویت را نیز پیکربندی نمایید.
GitLab نتایج تستها را (در صورت استفاده از فرمت گزارش JUnit) به صورت یکپارچه در صفحه Merge Request و در بخش Tests
پایپلاین نمایش میدهد. شما میتوانید لیست تستهای ناموفق را به همراه پیام خطای آنها مشاهده کنید. همچنین، با کلیک بر روی کار ناموفق، به لاگ کامل آن دسترسی خواهید داشت که جزئیات بیشتری را ارائه میدهد.
اجرای تستها فقط بر روی بخشهای تغییر یافته کد (Incremental Testing) میتواند پیچیده باشد و به ابزارها و استراتژیهای خاصی نیاز دارد. GitLab CI به طور پیشفرض تمام تستهای تعریف شده در اسکریپت را اجرا میکند. با این حال، شما میتوانید با اسکریپتنویسی سفارشی و استفاده از ابزارهایی که تغییرات فایل را تشخیص میدهند، این قابلیت را تا حدی پیادهسازی کنید. اغلب، اجرای کامل مجموعه تستهای واحد (که سریع هستند) بر روی هر تغییر، رویکرد مطمئنتری است.
stages
و jobs
در GitLab CI چیست؟ Stages
(مراحل) ترتیب کلی اجرای پایپلاین را تعریف میکنند (مثلاً ابتدا build
، سپس test
، و در نهایت deploy
). تمامی Jobs
(کارها) متعلق به یک مرحله، پس از موفقیت کامل مرحله قبلی، شروع به اجرا میکنند (و اگر منابع اجازه دهد، به صورت موازی). یک Job
واحدی از اجراست که یک اسکریپت خاص را روی یک Runner اجرا میکند.
ابتدا باید ابزار پوشش کد مناسب برای زبان و فریمورک خود را پیکربندی کنید تا گزارش پوشش کد را تولید نماید (معمولاً به فرمت XML مانند Cobertura یا به صورت متنی). سپس، در فایل .gitlab-ci.yml
، باید با استفاده از کلمه کلیدی coverage
یک عبارت منظم (regex) برای استخراج درصد پوشش از خروجی کنسول کار تست خود تعریف کنید. همچنین، میتوانید فایل گزارش کامل (مثلاً XML یا HTML) را به عنوان artifact
ذخیره کرده و با artifacts:reports:cobertura
آن را برای نمایش در GitLab UI مشخص کنید.
بیشتر بخوانید: