در دنیای پویای توسعه نرم‌افزار، اطمینان از کیفیت و پایداری محصول نقشی حیاتی ایفا می‌کند. تیم‌های تست و تضمین کیفیت (QA) در خط مقدم این مسئولیت قرار دارند و همواره به دنبال ابزارها و روش‌هایی برای بهبود فرآیند تست و افزایش کارایی هستند. یکی از چالش‌های بزرگ در این مسیر، ایجاد و مدیریت محیط‌های تست پایدار، قابل تکرار و ایزوله است. اینجاست که داکر (Docker) و به‌ویژه داکر کامپوز (Docker Compose) به عنوان یک راه‌حل قدرتمند وارد میدان می‌شوند. این مقاله به بررسی جامع چگونگی استفاده از داکر و داکر کامپوز برای ایجاد محیط‌های تست ایزوله توسط تسترها می‌پردازد.

چرا داکر برای تسترها یک تغییردهنده بازی است؟

قبل از ورود به جزئیات داکر کامپوز، بیایید درک کنیم که چرا داکر به خودی خود برای تسترها بسیار ارزشمند است:

  • پایان کابوس “روی سیستم من کار می‌کند!”: یکی از رایج‌ترین مشکلات در تیم‌های نرم‌افزاری، تفاوت بین محیط توسعه‌دهنده، محیط تست و محیط عملیاتی است. داکر با بسته‌بندی برنامه و تمام وابستگی‌های آن در یک کانتینر، تضمین می‌کند که برنامه در هر محیطی به طور یکسان اجرا شود. این امر به طور قابل توجهی تعداد باگ‌های ناشی از تفاوت محیط را کاهش می‌دهد.
  • ایزولاسیون کامل محیط تست: هر تست می‌تواند در یک محیط کانتینری کاملاً ایزوله اجرا شود. این بدان معناست که تست‌ها بر روی یکدیگر تأثیر نمی‌گذارند و نتایج تست‌ها قابل اعتمادتر خواهند بود. دیگر نگران تداخل داده‌ها یا تنظیمات بین تست‌های مختلف نخواهید بود.
  • راه‌اندازی و تخریب سریع محیط‌ها: ایجاد یک محیط تست سنتی می‌تواند زمان‌بر و پیچیده باشد. با داکر، می‌توانید محیط‌های پیچیده را در عرض چند ثانیه راه‌اندازی کرده و پس از اتمام تست، به همان سرعت آن‌ها را تخریب کنید. این سرعت و انعطاف‌پذیری برای تست‌های مکرر و چرخه‌های CI/CD حیاتی است.
  • تکرارپذیری و ثبات: Dockerfile ها و فایل‌های docker-compose.yml تعریف دقیقی از محیط را ارائه می‌دهند. این بدان معناست که هر بار که یک محیط را ایجاد می‌کنید، دقیقاً مشابه دفعه قبل خواهد بود، که برای بازتولید باگ‌ها و اطمینان از نتایج تست پایدار ضروری است.
  • مدیریت بهینه منابع: کانتینرهای داکر بسیار سبک‌تر از ماشین‌های مجازی (VMs) هستند. آن‌ها کرنل سیستم‌عامل میزبان را به اشتراک می‌گذارند و تنها شامل برنامه و وابستگی‌های آن هستند. این امر منجر به استفاده بهینه‌تر از منابع سخت‌افزاری و امکان اجرای همزمان تعداد بیشتری محیط تست می‌شود.
  • تست نسخه‌های مختلف: به راحتی می‌توانید نسخه‌های مختلفی از برنامه، پایگاه داده، یا سایر سرویس‌های وابسته را تست کنید بدون اینکه نیاز به پیکربندی مجدد کل محیط داشته باشید. کافی است ایمیج داکر مربوط به نسخه مورد نظر را تغییر دهید.

آشنایی با مفاهیم کلیدی داکر

قبل از اینکه به سراغ داکر کامپوز برویم، مروری کوتاه بر برخی مفاهیم اساسی داکر خواهیم داشت:

  • ایمیج داکر (Docker Image): یک قالب فقط خواندنی (read-only template) سبک، مستقل و قابل اجرا که شامل دستورالعمل‌هایی برای ایجاد یک کانتینر داکر است. ایمیج‌ها شامل کد برنامه، زمان اجرا (runtime)، کتابخانه‌ها، متغیرهای محیطی و فایل‌های پیکربندی هستند.
  • کانتینر داکر (Docker Container): یک نمونه در حال اجرای ایمیج داکر. کانتینرها محیطی ایزوله برای اجرای برنامه‌ها فراهم می‌کنند. می‌توان چندین کانتینر از یک ایمیج واحد ایجاد و اجرا کرد.
  • داکرفایل (Dockerfile): یک فایل متنی که شامل مجموعه‌ای از دستورالعمل‌ها برای ساخت یک ایمیج داکر است. این دستورالعمل‌ها به ترتیب اجرا شده و لایه‌های مختلف ایمیج را تشکیل می‌دهند.
  • داکر هاب (Docker Hub) / رجیستری (Registry): یک مخزن برای ذخیره و به اشتراک‌گذاری ایمیج‌های داکر. داکر هاب رجیستری عمومی و پیش‌فرض داکر است، اما می‌توانید رجیستری‌های خصوصی خود را نیز راه‌اندازی کنید.

داکر کامپوز (Docker Compose): ارکستراسیون محیط‌های چند کانتینری برای تست

در حالی که داکر به تنهایی برای مدیریت کانتینرهای منفرد عالی است، برنامه‌های کاربردی مدرن اغلب از چندین سرویس تشکیل شده‌اند که با یکدیگر تعامل دارند (مثلاً یک وب سرور، یک پایگاه داده، و یک سرویس کش). راه‌اندازی و مدیریت دستی این سرویس‌ها با دستورات docker run می‌تواند خسته‌کننده و مستعد خطا باشد.

اینجاست که داکر کامپوز وارد عمل می‌شود. داکر کامپوز ابزاری است که به شما امکان می‌دهد برنامه‌های چند کانتینری داکر را با استفاده از یک فایل پیکربندی YAML (معمولاً به نام docker-compose.yml) تعریف و اجرا کنید.

مزایای کلیدی استفاده از داکر کامپوز برای تسترها:

  • سادگی و خوانایی: تعریف کل پشته برنامه (application stack) در یک فایل YAML واحد، درک و مدیریت محیط را آسان می‌کند.
  • پیکربندی متمرکز: تمام تنظیمات مربوط به سرویس‌ها، شبکه‌ها و ولیوم (volumes) در یک مکان قرار می‌گیرند.
  • راه‌اندازی و توقف با یک دستور: با دستورات ساده‌ای مانند docker-compose up و docker-compose down می‌توانید کل محیط تست خود را راه‌اندازی یا متوقف کنید.
  • مدیریت وابستگی‌ها: داکر کامپوز به شما امکان می‌دهد ترتیب راه‌اندازی سرویس‌ها را مشخص کنید (مثلاً پایگاه داده قبل از برنامه اصلی راه‌اندازی شود).
  • ایجاد شبکه‌های ایزوله: به طور پیش‌فرض، داکر کامپوز یک شبکه اختصاصی برای سرویس‌های تعریف شده در فایل docker-compose.yml ایجاد می‌کند که ایزولاسیون بهتری را فراهم می‌کند.

راهنمای عملی: راه‌اندازی یک محیط تست ایزوله با داکر کامپوز

بیایید یک سناریوی رایج را در نظر بگیریم: تست یک برنامه وب که به یک پایگاه داده PostgreSQL نیاز دارد.

مرحله ۱: پیش‌نیازها

  • نصب داکر دسکتاپ (Docker Desktop) بر روی سیستم شما (که شامل داکر انجین و داکر کامپوز است).

مرحله ۲: ایجاد فایل docker-compose.yml

یک فایل با نام docker-compose.yml در ریشه پروژه خود ایجاد کنید و محتوای زیر را در آن قرار دهید:

version: '3.8' # مشخص کردن نسخه فایل کامپوز

services:
  webapp: # نام سرویس برنامه وب شما
    build: . # مسیر Dockerfile برنامه شما (در اینجا، در همین پوشه)
    # یا اگر ایمیج آماده دارید:
    # image: your-webapp-image:latest
    ports:
      - "8080:80" # مپ کردن پورت ۸۰۸۰ هاست به پورت ۸۰ کانتینر
    environment:
      - DB_HOST=db
      - DB_USER=testuser
      - DB_PASSWORD=testpass
      - DB_NAME=testdb
    depends_on:
      - db # مشخص می‌کند که سرویس وب‌اپ پس از سرویس دیتابیس راه‌اندازی شود

  db: # نام سرویس پایگاه داده
    image: postgres:13-alpine # استفاده از ایمیج رسمی PostgreSQL 13 نسخه Alpine
    restart: always # همیشه پس از توقف یا خطا، ریستارت شود
    environment:
      POSTGRES_USER: testuser
      POSTGRES_PASSWORD: testpass
      POSTGRES_DB: testdb
    volumes:
      - postgres_data:/var/lib/postgresql/data # ذخیره داده‌های پایگاه داده در یک वॉलوم برای پایداری

volumes:
  postgres_data: # تعریف یک named volume برای داده‌های پایگاه داده

توضیح بخش‌های کلیدی فایل docker-compose.yml:

  • version: نسخه سینتکس فایل داکر کامپوز را مشخص می‌کند.
  • services: در این بخش، سرویس‌های مختلف برنامه خود را تعریف می‌کنید.
    • webapp:
      • build: .: به داکر کامپوز می‌گوید که ایمیج این سرویس را با استفاده از Dockerfile موجود در پوشه فعلی بسازد. (اگر ایمیج از پیش ساخته شده‌ای دارید، می‌توانید از image: your-image-name استفاده کنید).
      • ports: پورت‌های هاست را به پورت‌های کانتینر مپ می‌کند (HOST_PORT:CONTAINER_PORT).
      • environment: متغیرهای محیطی را برای کانتینر تنظیم می‌کند. در اینجا، اطلاعات اتصال به پایگاه داده را به برنامه وب می‌دهیم.
      • depends_on: مشخص می‌کند که این سرویس به سرویس db وابسته است و باید پس از آن راه‌اندازی شود.
    • db:
      • image: postgres:13-alpine: از ایمیج رسمی PostgreSQL از داکر هاب استفاده می‌کند.
      • restart: always: تضمین می‌کند که کانتینر پایگاه داده در صورت بروز مشکل، به طور خودکار ریستارت شود.
      • environment: متغیرهای محیطی برای پیکربندی اولیه PostgreSQL (ایجاد کاربر و پایگاه داده).
      • volumespostgres_data:/var/lib/postgresql/data داده‌های پایگاه داده را در یک “named volume” به نام postgres_data ذخیره می‌کند. این کار باعث می‌شود داده‌ها حتی پس از توقف و حذف کانتینر پایگاه داده، باقی بمانند.
  • volumes: در این بخش، named volume ها تعریف می‌شوند.

مرحله ۳: ایجاد یک Dockerfile ساده برای برنامه وب (اختیاری، اگر از build استفاده می‌کنید)

اگر در docker-compose.yml از build: . برای سرویس webapp استفاده کرده‌اید، نیاز به یک Dockerfile در همان پوشه دارید. برای مثال، یک برنامه پایتون ساده با Flask:

Dockerfile:

# استفاده از ایمیج پایه پایتون
FROM python:3.9-slim

# تنظیم دایرکتوری کاری
WORKDIR /app

# کپی کردن فایل‌های نیازمندی‌ها
COPY requirements.txt requirements.txt

# نصب نیازمندی‌ها
RUN pip install -r requirements.txt

# کپی کردن بقیه کدهای برنامه
COPY . .

# پورت پیش‌فرض برنامه
EXPOSE 80

# دستور اجرای برنامه
CMD ["python", "app.py"]

requirements.txt:

Flask==2.0.1
psycopg2-binary # اگر برنامه شما با PostgreSQL ارتباط برقرار می‌کند

app.py (یک برنامه Flask ساده):

from flask import Flask
import os
import psycopg2

app = Flask(__name__)

@app.route('/')
def hello_world():
    try:
        conn = psycopg2.connect(
            host=os.getenv('DB_HOST'),
            database=os.getenv('DB_NAME'),
            user=os.getenv('DB_USER'),
            password=os.getenv('DB_PASSWORD')
        )
        conn.close()
        db_status = "Successfully connected to DB!"
    except Exception as e:
        db_status = f"Failed to connect to DB: {str(e)}"
    return f'Hello, Dockerized Tester! {db_status}'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

مرحله ۴: راه‌اندازی محیط

در ترمینال، به پوشه‌ای که فایل docker-compose.yml (و Dockerfile در صورت نیاز) در آن قرار دارد بروید و دستور زیر را اجرا کنید:

docker-compose up -d

  • -d (detached mode): کانتینرها را در پس‌زمینه اجرا می‌کند.

داکر کامپوز ابتدا ایمیج webapp را (اگر از build استفاده شده باشد) می‌سازد، سپس ایمیج postgres را دانلود می‌کند (اگر قبلاً دانلود نشده باشد) و در نهایت هر دو کانتینر را با تنظیمات مشخص شده راه‌اندازی می‌کند.

مرحله ۵: اجرای تست‌ها

اکنون محیط تست شما آماده است. برنامه وب شما از طریق http://localhost:8080 (یا پورت مپ شده دیگری) قابل دسترسی است و به پایگاه داده PostgreSQL که در کانتینر db در حال اجراست، متصل است. تسترهای اتومیشن (Automation Testers) می‌توانند اسکریپت‌های تست خود (مثلاً با Selenium، Cypress، Playwright، REST Assured) را بر روی این محیط اجرا کنند. نام هاست پایگاه داده برای برنامه وب شما db خواهد بود (نام سرویس تعریف شده در docker-compose.yml).

مرحله ۶: مشاهده لاگ‌ها (در صورت نیاز)

docker-compose logs webapp
docker-compose logs db

مرحله ۷: توقف و پاک‌سازی محیط

پس از اتمام تست‌ها، می‌توانید محیط را با دستور زیر متوقف و حذف کنید:

docker-compose down

این دستور کانتینرها و شبکه‌های ایجاد شده توسط داکر کامپوز را متوقف و حذف می‌کند. اگر می‌خواهید वॉलوم‌ها را نیز حذف کنید (که منجر به از دست رفتن داده‌های پایگاه داده در مثال ما می‌شود)، از دستور زیر استفاده کنید:

docker-compose down -v

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

  • ادغام با CI/CD: داکر کامپوز به راحتی با ابزارهای CI/CD مانند Jenkins، GitLab CI، یا GitHub Actions ادغام می‌شود. در پایپ‌لاین CI/CD، می‌توانید به طور خودکار محیط تست را با docker-compose up راه‌اندازی کنید، تست‌ها را اجرا کرده و سپس با docker-compose down آن را پاک‌سازی نمایید.
  • تست موازی: با استفاده از قابلیت‌های داکر و ابزارهای ارکستراسیون، می‌توانید چندین نمونه از محیط تست خود را به صورت موازی راه‌اندازی کنید تا زمان اجرای کل مجموعه تست‌ها کاهش یابد.
  • تست نسخه‌های مختلف سرویس‌ها: به سادگی با تغییر تگ ایمیج در فایل docker-compose.yml (مثلاً postgres:12-alpine به جای postgres:13-alpine) می‌توانید برنامه خود را در برابر نسخه‌های مختلف وابستگی‌ها تست کنید.
  • مدیریت داده‌های تست: از ولیوم‌های داکر برای مدیریت داده‌های تست اولیه (seed data) یا حفظ داده‌های تولید شده در طول تست برای بررسی‌های بعدی استفاده کنید.
  • بررسی‌های سلامت (Health Checks): در docker-compose.yml می‌توانید healthcheck برای سرویس‌ها تعریف کنید تا مطمئن شوید سرویس‌ها قبل از شروع تست‌ها یا وابستگی‌های دیگر به طور کامل آماده به کار هستند.
  • استفاده از فایل‌های .env: برای مدیریت متغیرهای محیطی حساس یا متغیر، می‌توانید از یک فایل .env در کنار docker-compose.yml استفاده کنید. داکر کامپوز به طور خودکار متغیرهای تعریف شده در این فایل را بارگذاری می‌کند.

چالش‌ها و ملاحظات

با وجود مزایای فراوان، استفاده از داکر و داکر کامپوز ممکن است با چالش‌هایی نیز همراه باشد:

  • منحنی یادگیری: درک مفاهیم داکر و سینتکس داکر کامپوز نیاز به زمان و تلاش اولیه دارد.
  • مصرف منابع: اگرچه کانتینرها سبک‌تر از VMها هستند، اما اجرای تعداد زیادی کانتینر همچنان می‌تواند منابع سیستمی قابل توجهی مصرف کند، به‌ویژه بر روی ماشین‌های توسعه با منابع محدود.
  • اشکال‌زدایی (Debugging): اشکال‌زدایی برنامه‌هایی که در داخل کانتینرها اجرا می‌شوند، می‌تواند کمی پیچیده‌تر از اشکال‌زدایی مستقیم بر روی سیستم میزبان باشد. ابزارهایی مانند docker logs و docker exec به این امر کمک می‌کنند.
  • امنیت: پیکربندی نادرست داکر می‌تواند منجر به آسیب‌پذیری‌های امنیتی شود. استفاده از ایمیج‌های رسمی و به‌روز، و محدود کردن دسترسی‌ها ضروری است.

آینده تست نرم‌افزار با داکر

داکر و کانتینرسازی به طور کلی، انقلابی در نحوه توسعه، استقرار و تست نرم‌افزار ایجاد کرده‌اند. برای تسترها، این فناوری به معنای توانایی ایجاد سریع محیط‌های تست ایزوله، قابل تکرار و پایدار است که منجر به افزایش کیفیت، کاهش زمان تست و همکاری بهتر در تیم می‌شود. با گسترش رویکردهای DevOps و “شیفت به چپ” (Shift-Left Testing)، نقش داکر در توانمندسازی تسترها برای مشارکت فعال‌تر و زودهنگام‌تر در چرخه توسعه، بیش از پیش پررنگ خواهد شد.

نتیجه‌گیری

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


سوالات متداول

تفاوت اصلی بین docker run و docker-compose up چیست؟ 

docker run برای راه‌اندازی و مدیریت یک کانتینر منفرد استفاده می‌شود. docker-compose up برای راه‌اندازی و مدیریت مجموعه‌ای از سرویس‌های (کانتینرهای) مرتبط که در فایل docker-compose.yml تعریف شده‌اند، به کار می‌رود. داکر کامپوز مدیریت برنامه‌های چند کانتینری را بسیار ساده‌تر می‌کند.

چگونه می‌توانم داده‌های تست خود را با داکر کامپوز مدیریت کنم؟

 شما می‌توانید از ولیوم‌های داکر (Docker Volumes) استفاده کنید. ولیوم‌ها به شما امکان می‌دهند داده‌ها را خارج از چرخه حیات کانتینر ذخیره کنید. می‌توانید داده‌های اولیه تست (seed data) را از طریق یک ولیوم به کانتینر پایگاه داده خود تزریق کنید یا داده‌های تولید شده توسط تست‌ها را برای بررسی‌های بعدی در یک ولیوم نگه دارید.

آیا داکر کامپوز برای تست‌های UI (مانند Selenium) مناسب است؟

 بله، بسیار مناسب است. شما می‌توانید برنامه وب خود و مرورگر (مثلاً Selenium Grid با کانتینرهای Chrome/Firefox) را با داکر کامپوز راه‌اندازی کنید. این کار تضمین می‌کند که تست‌های UI شما در یک محیط پایدار و قابل تکرار اجرا می‌شوند.

چگونه می‌توانم لاگ‌های سرویس‌های در حال اجرا با داکر کامپوز را مشاهده کنم؟

 می‌توانید از دستور docker-compose logs <service_name> برای مشاهده لاگ‌های یک سرویس خاص یا docker-compose logs برای مشاهده لاگ‌های تمام سرویس‌ها استفاده کنید. اضافه کردن آپشن -f (مثلاً docker-compose logs -f webapp) لاگ‌ها را به صورت زنده نمایش می‌دهد.

بیشتر بخوانید:

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