Skip to content

فصل ۹ — تست پشته‌های زیرساخت

این فصل رویهٔ اصلی تست و تحویل مداوم کد را به پشته‌های زیرساخت اعمال می‌کند. از مثال ShopSpinner برای نشان دادن نحوهٔ تست پروژهٔ پشته استفاده می‌کند. این شامل استفاده از مراحل تست آنلاین و آفلاین و بهره‌گیری از fixtureهای تست برای جداسازی پشته از وابستگی‌هاست.

زیرساخت نمونه

تیم ShopSpinner از پروژه‌های پشتهٔ قابل‌استفادهٔ مجدد (به «الگو: پشتهٔ قابل‌استفادهٔ مجدد» در صفحه ۷۲ مراجعه کنید) برای ایجاد نمونه‌های سازگار زیرساخت برنامه برای هر مشتری استفاده می‌کند. همچنین می‌تواند از این برای ایجاد نمونه‌های تست زیرساخت در خط لوله استفاده کند.

زیرساخت این مثال‌ها سیستم سه‌لایهٔ استاندارد است. زیرساخت در هر لایه شامل:

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

سرور برنامه زیرساخت هر نمونهٔ برنامه شامل ماشین مجازی، حجم دیسک پایدار و شبکه است. شبکه شامل بلوک آدرس، دروازه، مسیرها به سرور روی پورت شبکه و قوانین دسترسی شبکه است.

پایگاه داده ShopSpinner برای هر نمونهٔ برنامهٔ مشتری نمونهٔ پایگاه دادهٔ جداگانه با DBaaS ارائه‌دهنده اجرا می‌کند (به «منابع ذخیره‌سازی» در صفحه ۲۹ مراجعه کنید). کد زیرساخت ShopSpinner همچنین بلوک آدرس، مسیریابی و قوانین احراز هویت و دسترسی پایگاه داده را تعریف می‌کند.

پشتهٔ نمونه

برای شروع می‌توانیم یک پشتهٔ قابل‌استفادهٔ مجدد واحد تعریف کنیم که همهٔ زیرساخت به‌جز خوشهٔ سرور وب را دارد. ساختار پروژه می‌تواند مانند مثال ۹-۱ باشد.

مثال ۹-۱. پروژهٔ پشته برای برنامهٔ مشتری ShopSpinner

stack-project/
  └── src/
      ├── appserver_vm.infra
      ├── appserver_networking.infra
      ├── database.infra
      └── database_networking.infra

در این پروژه، فایل appserver_vm.infra کدی در خطوط مثال ۹-۲ دارد.

مثال ۹-۲. بخشی از محتوای appserver_vm.infra

virtual_machine:
  name: appserver-${customer}-${environment}
  ram: 4GB
  address_block: ADDRESS_BLOCK.appserver-${customer}-${environment}
  storage_volume: STORAGE_VOLUME.app-storage-${customer}-${environment}
  base_image: SERVER_IMAGE.shopspinner_java_server_image
  provision:
    tool: servermaker
    parameters:
      maker_server: maker.shopspinner.xyz
      role: appserver
      customer: ${customer}
      environment: ${environment}

storage_volume:
  id: app-storage-${customer}-${environment}
  size: 80GB
  format: xfs

عضو تیم یا فرآیند خودکار می‌تواند با اجرای ابزار پشته نمونه‌ای از پشته را ایجاد یا به‌روز کند. مقادیر را به نمونه با یکی از الگوهای فصل ۷ می‌دهند.

همان‌طور که در فصل ۸ توصیف شد، تیم از چند مرحلهٔ تست («تست تدریجی» در صفحه ۱۱۵) استفاده می‌کند که در خط لولهٔ توالی‌ای («خط‌ لوله‌های تحویل زیرساخت» در صفحه ۱۱۹) سازمان‌دهی شده‌اند.

خط لوله برای پشتهٔ نمونه

خط لولهٔ ساده برای پشتهٔ زیرساخت برنامهٔ ShopSpinner دو مرحلهٔ تست¹ دارد، به‌علاوهٔ مرحله‌ای که کد را به محیط تولید هر مشتری اعمال می‌کند (شکل ۹-۱).

شکل ۹-۱. خط لولهٔ نمونهٔ ساده برای یک پشته

مرحلهٔ اول خط لوله، مرحلهٔ ساخت پشته است. مرحلهٔ ساخت برای برنامه معمولاً کد را کامپایل می‌کند، تست‌های واحد (توصیف‌شده در «هرم تست» در صفحه ۱۱۶) را اجرا می‌کند و artifact قابل‌استقرار می‌سازد. جزئیات بیشتر مرحلهٔ ساخت معمولی برای کد زیرساخت را در «ساخت پروژهٔ زیرساخت» در صفحه ۳۲۲ ببینید. چون مراحل زودتر خط لوله باید سریع‌تر اجرا شوند، مرحلهٔ اول معمولاً برای تست‌های آفلاین استفاده می‌شود.

مرحلهٔ دوم خط لولهٔ نمونه تست‌های آنلاین برای پروژهٔ پشته را اجرا می‌کند. هر یک از مراحل خط لوله ممکن است بیش از یک مجموعهٔ تست اجرا کند.


¹ این خط لوله بسیار ساده‌تر از آنچه در واقعیت استفاده می‌کنید است. احتمالاً حداقل یک مرحله برای تست پشته و برنامه با هم دارید (به «تحویل زیرساخت و برنامه‌ها» در صفحه ۳۱۴ مراجعه کنید). شاید قبل از هر مرحلهٔ تولید مشتری به مرحلهٔ پذیرش مشتری هم نیاز دارید. این هم مراحل حاکمیت و تأیید را شامل نمی‌شود که بسیاری از سازمان‌ها می‌خواهند.

مراحل تست آفلاین برای پشته‌ها

مرحلهٔ آفلاین «محلی» روی گرهٔ عامل سرویسی که مرحله را اجرا می‌کند اجرا می‌شود (به «نرم‌افزار و سرویس‌های خط لولهٔ تحویل» در صفحه ۱۲۳ مراجعه کنید)، نه اینکه نیاز به تأمین زیرساخت روی پلتفرم زیرساخت شما داشته باشد. تست آفلاین سخت کاملاً درون سرور یا نمونهٔ کانتینر محلی اجرا می‌شود، بدون اتصال به سرویس خارجی مثل پایگاه داده. مرحلهٔ آفلاین نرم‌تر ممکن است به نمونهٔ سرویس موجود متصل شود، شاید حتی API ابری، اما از زیرساخت پشتهٔ واقعی استفاده نمی‌کند.

مرحلهٔ آفلاین باید:

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

برخی تست‌هایی که می‌توانید روی کد پشته در مرحلهٔ آفلاین انجام دهید: بررسی نحو، تحلیل ایستای کد آفلاین، تحلیل ایستای کد با API پلتفرم و تست با API mock.

بررسی نحو

با بیشتر ابزارهای پشته می‌توانید دستور dry run اجرا کنید که کد را بدون اعمال به زیرساخت parse می‌کند. دستور در صورت خطای نحو با خطا خارج می‌شود. بررسی خیلی سریع می‌گوید وقتی در تغییر کد اشتباه تایپی کرده‌اید، اما بسیاری خطاهای دیگر را از دست می‌دهد. نمونه‌های ابزارهای قابل‌اسکریپت بررسی نحو شامل terraform validate و aws cloudformation validate-template است.

خروجی بررسی نحوی شکست‌خورده ممکن است به این شکل باشد:

$ stack validate

Error: Invalid resource type

    on appserver_vm.infra line 1, in resource "virtual_mahcine":

stack does not support resource type "virtual_mahcine".

تحلیل ایستای کد آفلاین

برخی ابزارها می‌توانند کد منبع پشته را برای کلاس گسترده‌تری از مشکلات به‌جز نحو parse و تحلیل کنند، هنوز بدون اتصال به پلتفرم زیرساخت. این تحلیل اغلب linting نامیده می‌شود.² این نوع ابزار ممکن است به دنبال خطاهای کدنویسی، سبک گیج‌کننده یا ضعیف، رعایت سیاست سبک کد یا مشکلات امنیتی بالقوه باشد. برخی ابزارها حتی می‌توانند کد را برای مطابقت با سبک خاص تغییر دهند، مثل دستور terraform fmt.

ابزارهایی که کد زیرساخت را تحلیل کنند به‌اندازهٔ زبان‌های برنامه‌نویسی برنامه نیستند. نمونه‌ها شامل tflint، CloudFormation Linter، cfn_nag، tfsec و checkov است.

نمونهٔ خطا از ابزار تحلیل فرضی:

$ stacklint
1 issue(s) found:

Notice: Missing 'Name' tag (vms_must_have_standard_tags)

  on appserver_vm.infra line 1, in resource "virtual_machine":

در این مثال، قانون سفارشی vms_must_have_standard_tags داریم که همهٔ ماشین‌های مجازی باید مجموعه‌ای از برچسب‌ها از جمله Name داشته باشند.

تحلیل ایستای کد با API

بسته به ابزار، برخی بررسی‌های تحلیل ایستای کد ممکن است به API پلتفرم ابری متصل شوند تا تضاد با آنچه پلتفرم پشتیبانی می‌کند را بررسی کنند. مثلاً tflint می‌تواند کد پروژهٔ Terraform را بررسی کند تا مطمئن شود هر نوع نمونه (اندازهٔ ماشین مجازی) یا AMI (تصویر سرور) تعریف‌شده در کد واقعاً وجود دارد. برخلاف پیش‌نمایش تغییرات (به «پیش‌نمایش: دیدن تغییراتی که اعمال می‌شوند» در صفحه ۱۳۴ مراجعه کنید)، این نوع اعتبارسنجی کد را به‌طور کلی تست می‌کند، نه در برابر نمونهٔ پشتهٔ مشخص روی پلتفرم.

خروجی نمونهٔ زیر به‌خاطر تصویری که کد سرور مجازی اعلام می‌کند و روی پلتفرم وجود ندارد شکست می‌خورد:

$ stacklint
1 issue(s) found:

Notice: base_image 'SERVER_IMAGE.shopspinner_java_server_image' doesn't
  exist (validate_server_images)

  on appserver_vm.infra line 5, in resource "virtual_machine":

تست با API Mock

شاید بتوانید کد پشته را روی نمونهٔ mock محلی API پلتفرم زیرساخت اعمال کنید. ابزارهای mock این APIها زیاد نیستند. تنها ابزاری که تا زمان نگارش می‌شناسم Localstack است. برخی ابزارها بخش‌هایی از پلتفرم را mock می‌کنند، مثل Azurite که ذخیرهٔ blob و صف Azure را شبیه‌سازی می‌کند.

اعمال کد پشتهٔ اعلانی روی mock محلی می‌تواند خطاهای کدنویسی را آشکار کند که بررسی نحو یا تحلیل کد شاید پیدا نکند. در عمل، تست کد اعلانی با mockهای API پلتفرم زیرساخت خیلی ارزشمند نیست، به دلایلی که در «چالش: تست‌های کد اعلانی اغلب ارزش کمی دارند» در صفحه ۱۱۰ بحث شد. با این حال، این mockها ممکن است برای تست واحد کد امری (به «زبان‌های زیرساخت امری قابل‌برنامه‌ریزی» در صفحه ۴۳ مراجعه کنید)، به‌ویژه کتابخانه‌ها (به «ایجاد پویای عناصر پشته با کتابخانه‌ها» در صفحه ۲۷۳ مراجعه کنید) مفید باشند.


² اصطلاح lint از ابزار کلاسیک Unix می‌آید که کد منبع C را تحلیل می‌کند.

مراحل تست آنلاین برای پشته‌ها

مرحلهٔ آنلاین شامل استفاده از پلتفرم زیرساخت برای ایجاد و تعامل با نمونهٔ پشته است. این نوع مرحله کندتر است اما می‌تواند تست معنادارتری از تست‌های آفلاین انجام دهد. سرویس خط لولهٔ تحویل معمولاً ابزار پشته را روی یکی از گره‌ها یا عامل‌هایش اجرا می‌کند، اما از API پلتفرم برای تعامل با نمونهٔ پشته استفاده می‌کند. سرویس باید به API پلتفرم احراز هویت کند؛ برای ایده‌های مدیریت امن این به «مدیریت رازها به‌عنوان پارامتر» در صفحه ۱۰۲ مراجعه کنید.

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

مثلاً زیرساخت برنامهٔ مشتری ShopSpinner با پشتهٔ خوشهٔ سرور وب مشترک کار می‌کند. با این حال، اعضای تیم ShopSpinner زیرساخت، مراحل تست و تکنیک‌هایی را پیاده می‌کنند که امکان تست کد پشتهٔ برنامه بدون نمونهٔ خوشهٔ سرور وب را می‌دهد.

تکنیک‌های تقسیم پشته‌ها و نگه‌داشتن آن‌ها با اتصال شل را در فصل ۱۵ پوشش می‌دهم. با فرض ساخت زیرساخت به این شکل، می‌توانید از fixtureهای تست برای تست پشته به‌تنهایی استفاده کنید، همان‌طور که در «استفاده از fixtureهای تست برای مدیریت وابستگی‌ها» در صفحه ۱۳۷ توصیف شد.

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

پیش‌نمایش: دیدن تغییراتی که اعمال می‌شوند

برخی ابزارهای پشته می‌توانند کد پشته را با نمونهٔ پشته مقایسه کنند و تغییراتی که بدون تغییر واقعی اعمال می‌کند فهرست کند. زیردستور plan در Terraform نمونهٔ شناخته‌شده است.

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

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

مسئلهٔ دیگر این است که پیش‌نمایش‌های ابزار پشته معمولاً عمیق نیستند. پیش‌نمایش می‌گوید این کد سرور جدید ایجاد می‌کند:

virtual_machine:
  name: myappserver
  base_image: "java_server_image"

اما پیش‌نمایش ممکن است نگوید "java_server_image" وجود ندارد، اگرچه دستور apply در ایجاد سرور شکست می‌خورد.

پیش‌نمایش تغییرات پشته برای بررسی مجموعهٔ محدودی از ریسک‌ها بلافاصله قبل از اعمال تغییر کد به نمونه مفید است. اما برای تست کدی که قصد استفادهٔ مجدد در چند نمونه را دارید — مثل محیط‌های تست برای تحویل انتشار — کمتر مفید است. تیم‌هایی که از محیط‌های کپی-پیست استفاده می‌کنند (به «ضدالگو: محیط‌های کپی-پیست» در صفحه ۷۰ مراجعه کنید) اغلب مرحلهٔ پیش‌نمایش را به‌عنوان حداقل تست برای هر محیط استفاده می‌کنند. اما تیم‌هایی که از پشته‌های قابل‌استفادهٔ مجدد استفاده می‌کنند (به «الگو: پشتهٔ قابل‌استفادهٔ مجدد» در صفحه ۷۲ مراجعه کنید) می‌توانند از نمونه‌های تست برای اعتبارسنجی معنادارتر کد استفاده کنند.

تأیید: ادعا دربارهٔ منابع زیرساخت

با داشتن نمونهٔ پشته، می‌توانید در مرحلهٔ آنلاین تست‌هایی داشته باشید که دربارهٔ زیرساخت در پشته ادعا کنند. نمونه‌های چارچوب‌هایی برای تست منابع زیرساخت:

  • Awspec
  • Clarity
  • Inspec
  • Taskcat
  • Terratest

مجموعه‌ای از تست‌ها برای ماشین مجازی از کد پشتهٔ نمونهٔ قبلی در این فصل می‌تواند به این شکل باشد:

given virtual_machine(name: "appserver-testcustomerA-staging") {
  it { exists }
  it { is_running }
  it { passes_healthcheck }
  it { has_attached storage_volume(name: "app-storage-testcustomerA-staging") }
}

بیشتر ابزارهای تست پشته کتابخانه‌هایی برای نوشتن ادعا دربارهٔ انواع منابع زیرساختی که در فصل ۳ توصیف می‌کنم ارائه می‌دهند. این تست نمونه از منبع virtual_machine برای شناسایی VM در نمونهٔ پشته برای محیط staging استفاده می‌کند. چند ادعا دربارهٔ منبع می‌کند، از جمله آیا ایجاد شده (exists)، آیا در حال اجراست نه خاتمه‌یافته (is_running) و آیا پلتفرم زیرساخت آن را سالم می‌داند (passes_healthcheck).

ادعاهای ساده اغلب ارزش کمی دارند (به «چالش: تست‌های کد اعلانی اغلب ارزش کمی دارند» در صفحه ۱۱۰ مراجعه کنید)، چون فقط کد زیرساختی که تست می‌کنند را بازمی‌گویند. چند ادعای پایه (مثل exists) به بررسی سلامت کمک می‌کند که کد با موفقیت اعمال شده. این‌ها سریع مشکلات پایهٔ پیکربندی مرحلهٔ خط لوله یا اسکریپت‌های راه‌اندازی تست را شناسایی می‌کنند. تست‌هایی مثل is_running و passes_healthcheck وقتی ابزار پشته VM را با موفقیت ایجاد کرده اما crash کرده یا مشکل بنیادی دیگری دارد به شما می‌گویند. ادعاهای سادهٔ این‌گونه در اشکال‌زدایی وقت می‌گذارند.

اگرچه می‌توانید ادعاهایی بسازید که هر مورد پیکربندی VM را در کد پشته منعکس کنند، مثل مقدار RAM یا آدرس شبکهٔ اختصاص‌یافته، ارزش کمی دارند و سربار اضافه می‌کنند.

چهارمین ادعا در مثال، has_attached storage_volume()، جالب‌تر است. ادعا بررسی می‌کند حجم ذخیره‌سازی تعریف‌شده در همان پشته به VM متصل است. این اعتبارسنجی می‌کند ترکیب چند اعلان درست کار می‌کند (همان‌طور که در «تست ترکیب کد اعلانی» در صفحه ۱۱۲ بحث شد). بسته به پلتفرم و ابزار شما، کد پشته ممکن است با موفقیت اعمال شود اما سرور و حجم را درست به هم وصل نگذارد. یا ممکن است خطایی در کد پشته اتصال را بشکند.

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

virtual_machine:
  name: appserver-${customer}-${environment}
  address_block:
    if(${network_access} == "public")
      ADDRESS_BLOCK.public-${customer}-${environment}
    else
      ADDRESS_BLOCK.internal-${customer}-${environment}
    end

می‌توانید مرحلهٔ تستی داشته باشید که هر نوع نمونه را ایجاد و در هر مورد صحت پیکربندی شبکه را تأیید کند. باید تنوع‌های پیچیده‌تر را به ماژول‌ها یا کتابخانه‌ها منتقل کنید (به فصل ۱۶ مراجعه کنید) و آن ماژول‌ها را جدا از کد پشته تست کنید. این تست کد پشته را ساده می‌کند.

ادعای اینکه منابع زیرساخت طبق انتظار ایجاد شده‌اند تا حدی مفید است. اما ارزشمندترین تست اثبات این است که همان‌طور که باید کار می‌کنند.

نتایج: اثبات درست کار کردن زیرساخت

تست عملکردی بخش ضروری تست نرم‌افزار برنامه است. قیاس با زیرساخت اثبات این است که می‌توانید زیرساخت را همان‌طور که قصد دارید استفاده کنید. نمونه‌های نتایجی که می‌توانید با کد پشتهٔ زیرساخت تست کنید:

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

تست نتایج پیچیده‌تر از تأیید وجود چیزهاست. نه‌تنها تست‌ها باید نمونهٔ پشته را ایجاد یا به‌روز کنند، همان‌طور که در «الگوهای چرخهٔ عمر برای نمونه‌های تست پشته‌ها» در صفحه ۱۴۲ بحث می‌کنم، بلکه ممکن است نیاز به تأمین fixtureهای تست هم داشته باشید. fixture تست منبع زیرساختی است که فقط برای پشتیبانی تست به کار می‌رود (در «استفاده از fixtureهای تست برای مدیریت وابستگی‌ها» در صفحه ۱۳۷ دربارهٔ fixtureهای تست صحبت می‌کنم).

این تست به سرور متصل می‌شود تا بررسی کند پورت در دسترس است و پاسخ HTTP مورد انتظار برمی‌گرداند:

given stack_instance(stack: "shopspinner_networking",
                     instance: "online_test") {

    can_connect(ip_address: stack_instance.appserver_ip_address,
                port:443)

    http_request(ip_address: stack_instance.appserver_ip_address,
                port:443,
                url: '/').response.code is('200')

}

چارچوب تست و کتابخانه‌ها جزئیات اعتبارسنجی‌هایی مثل can_connect و http_request را پیاده می‌کنند. باید مستندات ابزار تست خود را بخوانید تا ببینید چگونه تست واقعی بنویسید.

استفاده از fixtureهای تست برای مدیریت وابستگی‌ها

بسیاری از پروژه‌های پشته به منابعی که خارج از پشته ایجاد شده‌اند وابسته‌اند، مثل شبکهٔ مشترک تعریف‌شده در پروژهٔ پشتهٔ دیگر. fixture تست منبع زیرساختی است که مخصوصاً برای کمک به تأمین و تست نمونهٔ پشته به‌تنهایی، بدون نیاز به نمونه‌های پشته‌های دیگر ایجاد می‌کنید. test double، ذکرشده در «چالش: وابستگی‌ها تست زیرساخت را پیچیده می‌کنند» در صفحه ۱۱۴، نوعی fixture تست است.

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

fixture تست بخشی از پشته‌ای که تست می‌کنید نیست. زیرساخت اضافی است که برای پشتیبانی تست‌ها ایجاد می‌کنید. از fixtureهای تست برای نمایندگی وابستگی‌های یک پشته استفاده می‌کنید.

وابستگی مشخص یا upstream است، یعنی پشته‌ای که تست می‌کنید از منابعی که پشتهٔ دیگر تأمین می‌کند استفاده می‌کند، یا downstream است که در آن پشته‌های دیگر از منابع پشته‌ای که تست می‌کنید استفاده می‌کنند. گاهی پشته‌ای با وابستگی‌های downstream را provider می‌نامند چون منابع تأمین می‌کند. پشته با وابستگی‌های upstream consumer نامیده می‌شود (شکل ۹-۲).

شکل ۹-۲. نمونهٔ پشتهٔ provider و consumer

مثال ShopSpinner پشتهٔ provider دارد که ساختارهای شبکهٔ مشترک را تعریف می‌کند. این ساختارها توسط پشته‌های consumer، از جمله پشته‌ای که زیرساخت برنامهٔ مشتری را تعریف می‌کند، استفاده می‌شوند. پشتهٔ برنامه سروری ایجاد و به بلوک آدرس شبکه اختصاص می‌دهد.³


³ فصل ۱۷ نحوهٔ اتصال وابستگی‌های پشته را توضیح می‌دهد.

یک پشته ممکن است هم provider و هم consumer باشد — منابعی از پشتهٔ دیگر مصرف و منابعی به پشته‌های دیگر تأمین کند. می‌توانید از fixtureهای تست برای جایگزینی نقاط یکپارچه‌سازی upstream یا downstream یک پشته استفاده کنید.

test double برای وابستگی‌های upstream

وقتی باید پشته‌ای را تست کنید که به پشتهٔ دیگر وابسته است، می‌توانید test double ایجاد کنید. برای پشته‌ها این معمولاً یعنی ایجاد زیرساخت اضافی. در مثال پشتهٔ شبکهٔ مشترک و پشتهٔ برنامه، پشتهٔ برنامه باید سرورش را در بلوک آدرس شبکه‌ای که پشتهٔ شبکه تعریف می‌کند ایجاد کند. راه‌اندازی تست شاید بتواند بلوک آدرس را به‌عنوان fixture تست ایجاد کند تا پشتهٔ برنامه را جداگانه تست کند.

ممکن است بهتر باشد بلوک آدرس را به‌عنوان fixture تست ایجاد کنید تا نمونهٔ کل پشتهٔ شبکه. پشتهٔ شبکه ممکن است زیرساخت اضافی داشته باشد که برای تست لازم نیست. مثلاً ممکن است سیاست‌های شبکه، مسیرها، ممیزی و منابع دیگر برای تولید تعریف کند که برای تست زیاده‌روی است.

همچنین ایجاد وابستگی به‌عنوان fixture تست درون پروژهٔ پشتهٔ consumer آن را از پشتهٔ provider جدا می‌کند. اگر کسی روی تغییر پروژهٔ پشتهٔ شبکه کار کند، روی کار پشتهٔ برنامه تأثیر نمی‌گذارد.

مزیت بالقوهٔ این نوع جداسازی، قابل‌استفاده‌تر و ترکیب‌پذیرتر شدن پشته‌هاست. تیم ShopSpinner شاید بخواهد پروژه‌های پشتهٔ شبکهٔ مختلف برای اهداف مختلف بسازد. یک پشته شبکهٔ tightly controlled و ممیزی‌شده برای سرویس‌هایی با نیازهای انطباق سخت‌تر، مثل پردازش پرداخت تحت استاندارد PCI یا مقررات حفاظت دادهٔ مشتری. پشتهٔ دیگر شبکه‌ای ایجاد می‌کند که نیازی به انطباق PCI ندارد. با تست پشته‌های برنامه بدون استفاده از هیچ‌کدام از این پشته‌ها، تیم استفاده از کد پشته با هر کدام را آسان‌تر می‌کند.

fixtureهای تست برای وابستگی‌های downstream

همچنین می‌توانید از fixtureهای تست برای موقعیت معکوس استفاده کنید — تست پشته‌ای که منابعی برای استفادهٔ پشته‌های دیگر تأمین می‌کند. در شکل ۹-۳، نمونهٔ پشته ساختارهای شبکه برای ShopSpinner از جمله بخش‌ها و مسیریابی برای خوشهٔ کانتینر سرور وب و سرورهای برنامه تعریف می‌کند. پشتهٔ شبکه خوشهٔ کانتینر یا سرورهای برنامه را تأمین نمی‌کند، پس برای تست شبکه، راه‌اندازی fixture تستی در هر یک از این بخش‌ها تأمین می‌کند.

شکل ۹-۳. نمونهٔ تست پشتهٔ شبکه ShopSpinner، با fixtureهای تست

fixtureهای تست در این مثال‌ها جفت نمونهٔ کانتینر هستند، یکی به هر بخش شبکه در پشته اختصاص‌یافته. اغلب می‌توانید همان ابزارهای تستی که برای تست تأیید استفاده می‌کنید (به «تأیید: ادعا دربارهٔ منابع زیرساخت» در صفحه ۱۳۵ مراجعه کنید) برای تست نتایج به کار ببرید. این تست‌های نمونه از DSL تست پشتهٔ فرضی استفاده می‌کنند:

given stack_instance(stack: "shopspinner_networking",
                     instance: "online_test") {

    can_connect(from: $HERE,
                to: get_fixture("web_segment_instance").address,
                port:443)

    can_connect(from: get_fixture("web_segment_instance"),
                to: get_fixture("app_segment_instance").address,
                port: 8443)

}

متد can_connect از $HERE اجرا می‌شود که گره‌ای است که کد تست روی آن اجرا می‌شود، یا از نمونهٔ کانتینر. سعی می‌کند اتصال HTTPS روی پورت مشخص به آدرس IP برقرار کند. متد get_fixture() جزئیات نمونهٔ کانتینری که به‌عنوان fixture تست ایجاد شده را می‌گیرد.

چارچوب تست ممکن است متد can_connect را ارائه دهد، یا می‌تواند متد سفارشی باشد که تیم می‌نویسد.

اتصالاتی که کد تست نمونه برقرار می‌کند را در شکل ۹-۴ می‌بینید.

شکل ۹-۴. تست اتصال‌پذیری در پشتهٔ شبکه ShopSpinner

نمودار مسیر هر دو تست را نشان می‌دهد. تست اول از خارج پشته به fixture در بخش وب متصل می‌شود. تست دوم از fixture در بخش وب به fixture در بخش برنامه متصل می‌شود.

بازآرایی مؤلفه‌ها برای جداسازی‌پذیری

گاهی مؤلفهٔ خاصی را نمی‌توان به‌راحتی جدا کرد. وابستگی‌ها به مؤلفه‌های دیگر ممکن است سخت‌کد شده یا خیلی آشفته باشند. یکی از مزایای نوشتن تست هنگام طراحی و ساخت سیستم‌ها، نه بعداً، این است که شما را وادار به بهبود طراحی می‌کند. مؤلفه‌ای که تست جداگانه‌اش دشوار است نشانهٔ مشکلات طراحی است. سیستم خوب‌طراحی‌شده باید مؤلفه‌های با اتصال شل داشته باشد.

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

چند راهبرد برای بازساخت سیستم‌ها وجود دارد. Martin Fowler دربارهٔ بازآرایی و تکنیک‌های دیگر بهبود معماری سیستم نوشته. مثلاً Strangler Application اولویت را به نگه‌داشتن سیستم کاملاً در حال کار هنگام بازساخت تدریجی می‌دهد.

بخش IV این کتاب قوانین و مثال‌های دقیق‌تری برای ماژولار کردن و یکپارچه‌سازی زیرساخت دارد.

الگوهای چرخهٔ عمر برای نمونه‌های تست پشته‌ها

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

الگو: پشتهٔ تست پایدار

همچنین شناخته‌شده به‌عنوان: محیط ثابت.

مرحلهٔ تست می‌تواند از نمونهٔ پشتهٔ تست پایدار که همیشه در حال اجراست استفاده کند. مرحله هر تغییر کد را به‌عنوان به‌روزرسانی روی نمونهٔ پشتهٔ موجود اعمال می‌کند، تست‌ها را اجرا می‌کند و پشتهٔ اصلاح‌شده را برای اجرای بعدی سر جایش می‌گذارد (شکل ۹-۵).

شکل ۹-۵. نمونهٔ پشتهٔ تست پایدار

انگیزه

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

کاربرد

پشتهٔ تست پایدار وقتی مفید است که بتوانید کد پشته را به‌طور قابل‌اطمینان روی نمونه اعمال کنید. اگر وقت زیادی صرف تعمیر نمونه‌های شکسته برای راه‌اندازی دوباره خط لوله می‌کنید، باید یکی از الگوهای دیگر این فصل را در نظر بگیرید.

تبعات

غیرمعمول نیست نمونه‌های پشته «گیر کنند» (wedged) وقتی تغییری شکست می‌خورد و آن‌ها را در حالتی می‌گذارد که هر تلاش جدید برای اعمال کد پشته هم شکست می‌خورد. اغلب نمونه آن‌قدر گیر می‌کند که ابزار پشته حتی نمی‌تواند پشته را نابود کند تا از نو شروع کنید. پس تیم شما وقت زیادی صرف unwedging دستی نمونه‌های تست شکسته می‌کند.

می‌توانید با طراحی بهتر پشته فراوانی گیرکردن را کاهش دهید. تقسیم پشته‌ها به پشته‌های کوچک‌تر و ساده‌تر و ساده‌سازی وابستگی‌ها بین پشته‌ها می‌تواند نرخ گیرکردن را پایین بیاورد. بیشتر در فصل ۱۵.

پیاده‌سازی

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

شاید گاهی پشته را کاملاً بازسازی کنید به‌عنوان فرآیند ad hoc، مثلاً کسی از رایانهٔ محلی ابزار را اجرا کند یا مرحله یا job اضافی خارج از جریان معمول خط لوله.

الگوهای مرتبط

الگوی بازسازی دوره‌ای پشته در «الگو: بازسازی دوره‌ای پشته» در صفحه ۱۴۶ تغییر ساده‌ای روی این الگو است — نابودی نمونه در پایان روز کاری و ساخت نمونهٔ جدید هر صبح.

الگو: پشتهٔ تست زودگذر

همچنین شناخته‌شده به‌عنوان: سریع و کثیف به‌علاوهٔ کند و تمیز.

با الگوی پشتهٔ تست زودگذر، مرحلهٔ تست هر بار که اجرا می‌شود نمونهٔ جدیدی از پشته ایجاد و نابود می‌کند (شکل ۹-۶).

شکل ۹-۶. نمونهٔ پشتهٔ تست زودگذر

انگیزه

پشتهٔ تست زودگذر محیط تمیزی برای هر اجرای تست فراهم می‌کند. ریسکی از داده، fixture یا «آشغال» باقی‌مانده از اجرای قبلی نیست.

کاربرد

شاید بخواهید برای پشته‌هایی که از صفر سریع تأمین می‌شوند از نمونه‌های زودگذر استفاده کنید. «سریع» نسبت به حلقهٔ بازخوردی است که شما و تیم‌هایتان نیاز دارید. برای تغییرات مکررتر، مثل commit به کد برنامه در فازهای توسعهٔ سریع، زمان ساخت محیط جدید احتمالاً بیشتر از تحمل افراد است. اما تغییرات کمتر مکرر، مثل به‌روزرسانی وصلهٔ OS، شاید با بازسازی کامل قابل‌قبول تست شوند.

تبعات

پشته‌ها معمولاً از صفر تأمین شدن زمان زیادی می‌برند. پس مراحلی که از نمونه‌های پشتهٔ زودگذر استفاده می‌کنند حلقه‌های بازخورد و چرخه‌های تحویل را کندتر می‌کنند.

پیاده‌سازی

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

الگوهای مرتبط

الگوی بازنشانی مداوم پشته («الگو: بازنشانی مداوم پشته» در صفحه ۱۴۷) مشابه است، اما دستورات ایجاد و نابود پشته را خارج از مرحله اجرا می‌کند تا زمان صرف‌شده روی بازخورد تأثیر نگذارد.

ضدالگو: مراحل پشتهٔ پایدار و زودگذر دوتایی

همچنین شناخته‌شده به‌عنوان: بازسازی شبانه.

با مراحل پشتهٔ پایدار و زودگذر، خط لوله هر تغییر پشته را به دو مرحلهٔ مختلف می‌فرستد — یکی با نمونهٔ پشتهٔ زودگذر و یکی با نمونهٔ پشتهٔ پایدار. این الگوی پشتهٔ تست پایدار (به «الگو: پشتهٔ تست پایدار» در صفحه ۱۴۲ مراجعه کنید) و الگوی پشتهٔ تست زودگذر (به «الگو: پشتهٔ تست زودگذر» در صفحه ۱۴۳ مراجعه کنید) را ترکیب می‌کند.

انگیزه

تیم‌ها معمولاً این را برای دور زدن معایب هر دو الگویی که ترکیب می‌کند پیاده می‌کنند. اگر همه خوب پیش برود، مرحلهٔ «سریع و کثیف» (با نمونهٔ پایدار) بازخورد سریع می‌دهد. اگر آن مرحله به‌خاطر گیرکردن محیط شکست بخورد، در نهایت از مرحلهٔ «کند و تمیز» (با نمونهٔ زودگذر) بازخورد می‌گیرید.

کاربرد

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

تبعات

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

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

پیاده‌سازی

مراحل دوتایی را با ایجاد دو مرحلهٔ خط لوله پیاده می‌کنید، هر دو توسط مرحلهٔ قبلی خط لوله برای پروژهٔ پشته راه‌اندازی می‌شوند، همان‌طور که در شکل ۹-۷ نشان داده شده. ممکن است بخواهید هر دو مرحله عبور کنند قبل از ارتقای نسخهٔ پشته به مرحلهٔ بعد، یا وقتی یکی از مراحل عبور کرد ارتقا دهید.

شکل ۹-۷. مراحل پشتهٔ پایدار و زودگذر دوتایی

الگوهای مرتبط

این ضدالگو الگوی پشتهٔ تست پایدار (به «الگو: پشتهٔ تست پایدار» در صفحه ۱۴۲ مراجعه کنید) و الگوی پشتهٔ تست زودگذر (به «الگو: پشتهٔ تست زودگذر» در صفحه ۱۴۳ مراجعه کنید) را ترکیب می‌کند.

الگو: بازسازی دوره‌ای پشته

بازسازی دوره‌ای پشته از نمونهٔ پشتهٔ تست پایدار (به «الگو: پشتهٔ تست پایدار» در صفحه ۱۴۲ مراجعه کنید) برای مرحلهٔ تست پشته استفاده می‌کند و سپس فرآیندی دارد که خارج از باند اجرا می‌شود تا نمونهٔ پشته را طبق برنامه، مثلاً شبانه، نابود و بازسازی کند.

انگیزه

اغلب از بازسازی‌های دوره‌ای برای کاهش هزینه استفاده می‌شود. پشته را در پایان روز کاری نابود و در شروع روز بعد نمونهٔ جدید تأمین می‌کنند.

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

کاربرد

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

نابود نمونهٔ پشته وقتی استفاده نمی‌شود برای صرفه‌جویی هزینه منطقی است، به‌ویژه با منابع اندازه‌گیری‌شده مثل پلتفرم‌های ابر عمومی.

تبعات

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

پیاده‌سازی

بیشتر ابزارهای ارکستراسیون خط لوله ساخت jobهایی که طبق برنامه اجرا می‌شوند برای نابود و ساخت نمونه‌های پشته را آسان می‌کنند. راه‌حل پیشرفته‌تر بر اساس سطح فعالیت اجرا می‌شود. مثلاً jobی که نمونه را نابود کند اگر مرحلهٔ تست در ساعت گذشته اجرا نشده.

سه گزینه برای راه‌اندازی ساخت نمونهٔ تازه پس از نابود نمونهٔ قبلی وجود دارد. یکی بازسازی فوری پس از نابود است. این منابع را پاک می‌کند اما هزینه صرفه‌جویی نمی‌کند.

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

گزینهٔ سوم این است که مرحلهٔ تست نمونهٔ جدید تأمین کند اگر الان در حال اجرا نیست. job جداگانه‌ای نمونه را نابود کند، یا طبق برنامه یا پس از دورهٔ عدم فعالیت. هر بار مرحلهٔ تست اجرا می‌شود، ابتدا بررسی می‌کند آیا نمونه در حال اجراست. اگر نه، ابتدا نمونهٔ جدید تأمین می‌کند. با این رویکرد، گاهی افراد باید بیشتر از معمول برای نتایج تست منتظر بمانند. اگر اولین کسی باشند که صبح تغییر push می‌کنند، باید منتظر تأمین پشته توسط سیستم بمانند.

الگوهای مرتبط

این الگو می‌تواند مانند الگوی پشتهٔ تست پایدار عمل کند (به «الگو: پشتهٔ تست پایدار» در صفحه ۱۴۲ مراجعه کنید) — اگر به‌روزرسانی‌های پشته غیرقابل‌اطمینان باشد، افراد وقت صرف تعمیر نمونه‌های شکسته می‌کنند.

الگو: بازنشانی مداوم پشته

با الگوی بازنشانی مداوم پشته، هر بار مرحلهٔ تست پشته تکمیل می‌شود، job خارج از باند نمونهٔ پشته را نابود و بازسازی می‌کند (شکل ۹-۸).

شکل ۹-۸. جریان خط لوله برای بازنشانی مداوم پشته

انگیزه

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

مزیت دیگر این الگو این است که می‌تواند فرآیند به‌روزرسانی که در تولید برای نسخهٔ مشخص کد پشته رخ می‌دهد را به‌طور قابل‌اطمینان تست کند.

کاربرد

نابود نمونهٔ پشته در پس‌زمینه می‌تواند خوب کار کند اگر پروژهٔ پشته تمایل به شکستن و نیاز به مداخلهٔ دستی برای تعمیر نداشته باشد.

تبعات

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

پیاده‌سازی

وقتی مرحلهٔ تست عبور می‌کند، کد پروژهٔ پشته را به مرحلهٔ بعد ارتقا می‌دهد. همچنین jobی برای نابود و بازسازی نمونهٔ پشته راه‌اندازی می‌کند. وقتی کسی تغییر جدیدی به کد push می‌کند، مرحلهٔ تست آن را به‌عنوان به‌روزرسانی روی نمونه اعمال می‌کند.

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

الگوهای مرتبط

ایده‌آل این است که این الگو شبیه الگوی پشتهٔ تست پایدار (به «الگو: پشتهٔ تست پایدار» در صفحه ۱۴۲ مراجعه کنید) باشد و بازخورد بدهد، در حالی که قابلیت اطمینان الگوی پشتهٔ تست زودگذر (به «الگو: پشتهٔ تست زودگذر» در صفحه ۱۴۳ مراجعه کنید) را داشته باشد.

ارکستراسیون تست

هر یک از بخش‌های متحرک تست پشته‌ها را توصیف کردم: انواع تست‌ها و اعتبارسنجی‌هایی که می‌توانید اعمال کنید، استفاده از fixtureهای تست برای مدیریت وابستگی‌ها و چرخه‌های عمر برای نمونه‌های تست پشته. اما چگونه این‌ها را کنار هم بگذارید تا تست‌ها را راه‌اندازی و اجرا کنید؟

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

ارکستراسیون تست ممکن است شامل:

  • ایجاد fixtureهای تست
  • بارگذاری دادهٔ تست (بیشتر برای تست برنامه لازم است تا تست زیرساخت)
  • مدیریت چرخهٔ عمر نمونه‌های تست پشته
  • دادن پارامترها به ابزار تست
  • اجرای ابزار تست
  • تجمیع نتایج تست
  • پاک‌سازی نمونه‌های تست، fixtureها و داده

بیشتر این موضوعات، مثل fixtureهای تست و چرخه‌های عمر نمونهٔ پشته، قبلاً در این فصل پوشش داده شد. بقیه، از جمله اجرای تست‌ها و تجمیع نتایج، به ابزار خاص بستگی دارد.

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

پشتیبانی از تست محلی

افرادی که روی کد پشتهٔ زیرساخت کار می‌کنند باید بتوانند خودشان قبل از push کد به خط لوله و محیط‌های مشترک تست‌ها را اجرا کنند. «نمونه‌های زیرساخت شخصی» در صفحه ۳۴۷ رویکردهایی برای کمک به افراد برای کار با نمونه‌های پشتهٔ شخصی روی پلتفرم زیرساخت بحث می‌کند. این امکان کدنویسی و اجرای تست‌های آنلاین قبل از push تغییرات را می‌دهد.

علاوه بر کار با نمونه‌های تست شخصی پشته‌ها، افراد باید ابزارهای تست و عناصر دیگر درگیر در اجرای تست را در محیط کاری محلی داشته باشند. بسیاری از تیم‌ها از محیط‌های توسعهٔ مبتنی بر کد استفاده می‌کنند که نصب و پیکربندی ابزارها را خودکار می‌کند. می‌توانید از کانتینر یا ماشین مجازی برای بسته‌بندی محیط‌های توسعه که روی انواع مختلف سیستم‌های دسکتاپ اجرا می‌شوند استفاده کنید.⁴ به‌طور جایگزین، تیم شما می‌تواند از ایستگاه‌های کاری میزبانی‌شده (امیدوارانه پیکربندی‌شده به‌عنوان کد) استفاده کند، اگرچه این‌ها ممکن است از تأخیر، به‌ویژه برای تیم‌های توزیع‌شده، رنج ببرند.

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

اجتناب از گره‌خوردگی تنگ با ابزارهای خط لوله

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

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

ابزارهای ارکستراسیون تست

بسیاری از تیم‌ها اسکریپت‌های سفارشی برای ارکستراسیون تست می‌نویسند. این اسکریپت‌ها شبیه یا حتی همان اسکریپت‌هایی هستند که برای ارکستراسیون مدیریت پشته استفاده می‌شوند (همان‌طور که در «استفاده از اسکریپت‌ها برای پوشش ابزارهای زیرساخت» در صفحه ۳۳۵ توصیف شد). افراد از اسکریپت Bash، فایل batch، Ruby، Python، Make، Rake و موارد دیگری که نشنیده‌ام استفاده می‌کنند.

چند ابزار مخصوصاً برای ارکستراسیون تست زیرساخت طراحی شده‌اند. دو موردی که می‌شناسم Test Kitchen و Molecule است. Test Kitchen محصول متن‌باز Chef است که در ابتدا برای تست Chef cookbookها بود. Molecule ابزار متن‌باز برای تست Ansible playbookها است. می‌توانید هر دو را برای تست پشته‌های زیرساخت استفاده کنید، مثلاً با Kitchen-Terraform.


⁴ Vagrant برای اشتراک پیکربندی ماشین مجازی بین اعضای تیم مفید است.

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

جمع‌بندی

این فصل نمونه‌ای از ایجاد خط لوله با چند مرحله برای پیاده‌سازی رویهٔ اصلی تست و تحویل مداوم کد سطح پشته داد. یکی از چالش‌های تست کد پشته ابزار است. اگرچه ابزارهایی وجود دارد — بسیاری را در این فصل ذکر کردم — TDD، CI و تست خودکار تا زمان نگارش برای زیرساخت خیلی جا نیفتاده‌اند. سفری دارید تا ابزارهایی که می‌توانید استفاده کنید کشف کنید و شاید شکاف‌های ابزار را با اسکریپت‌نویسی سفارشی پر کنید. امیدوارم این با گذشت زمان بهبود یابد.


بخش III

کار با سرورها و سایر پلتفرم‌های زمان اجرای برنامه