Angular CLI - قسمت هفتم - اجرای آزمون‌ها
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: شش دقیقه

پروژه‌های Angular CLI در حالت پیش فرض آن‌ها به همراه دو نوع آزمون واحد و آزمون end to end ایجاد می‌شوند. Angular CLI از Karma برای اجرای آزمون‌های واحد استفاده می‌کند و از Protractor برای اجرای آزمون‌های end to end. برای شروع می‌توان از راهنمای آن کمک گرفت:
 > ng test --help
زمانیکه دستور ng test را اجرا می‌کنیم، به صورت خودکار تمام فایل‌های spec.ts.* را یافته و آزمون‌های واحد موجود در آن‌ها را اجرا می‌کند. این نوع فایل‌های ویژه نیز به صورت خودکار، زمانیکه اجزای مختلف Angular را توسط Angular CLI ایجاد می‌کنیم، تولید می‌شوند. به علاوه دستور ng test تغییرات این فایل‌ها را تحت نظر قرار داده و در صورت نیاز، آزمون‌های واحد را مجددا و به صورت خودکار اجرا می‌کند.


یک مثال: بررسی اجرای دستور ng test

یکی از مثال‌های بررسی شده‌ی در این سری را انتخاب و یا حتی یک برنامه‌ی جدید را توسط Angular CLI ایجاد کرده و سپس دستور ng test را در ریشه‌ی این پروژه اجرا کنید. به این ترتیب برنامه به صورت خودکار کامپایل شده و سپس به صورت خودکار آزمون‌های واحد آن‌را که در فایل‌های spec.ts‌.* قرار دارند، اجرا می‌کند. در آخر نتیجه را در مرورگر گزارش می‌دهد:


همانطور که مشخص است، 3 specs, 3 failures داریم. در اینجا می‌توان بر روی لینک Spec List کلیک کرد و لیست آزمون‌های واحد موجود را مشاهده نمود:


هر کدام از عناوین ذکر شده نیز به جزئیات مشکلات آن‌ها، لینک شده‌اند. برای مثال اگر بر روی اولین مورد کلیک کنیم، خطایی مانند «'alert' is not a known element» قابل مشاهده‌است. به این معنا که برای نمونه در قسمت قبل کامپوننت alert را به صفحه اضافه کردیم:
 <alert type="success">Alert success!</alert>
اما اجرا کننده‌ی آزمون‌های واحد اطلاعاتی در مورد آن ندارد؛ از این جهت که آزمون‌های واحد به صورت ایزوله فقط همان کامپوننت خاص برنامه را آزمایش می‌کنند و کاری به وابستگی‌های آن ندارد. به همین جهت فایل src\app\app.component.spec.ts را گشوده و تغییرات ذیل را به آن اعمال کنید:
import { NO_ERRORS_SCHEMA } from '@angular/core';

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
  schemas: [NO_ERRORS_SCHEMA]
    }).compileComponents();
  }));
در اینجا ابتدا ماژول NO_ERRORS_SCHEMA معرفی شده و سپس به قسمت schemas معرفی گشته‌است.
پس از این تغییر، بلافاصله مجدد برنامه کامپایل شده و آزمون‌های واحد آن با موفقیت اجرا می‌شوند (با این فرض که هنوز پنجره‌ی اجرا کننده‌ی دستور ng test را باز نگه داشته‌اید):


تغییر افزودن schemas: [NO_ERRORS_SCHEMA] را باید در مورد تمام فایل‌های spec موجود تکرار کرد.


گزینه‌های مختلف دستور ng test

دستور ng test به همراه گزینه‌های متعددی است که شرح آن‌ها را در جدول ذیل مشاهده می‌کنید:

گزینه
 مخفف  توضیح
 code-coverage--  cc-   تولید گزارش code coverage که به صورت پیش فرض خاموش است. 
 colors--     به صورت پیش فرض فعال است و سبب نمایش رنگ‌های قرمز و سبز، برای آزمون‌های شکست خورده و یا موفق می‌شود. 
 single-run--  sr-   اجرای یکباره‌ی آزمون‌های واحد، بدون فعال سازی گزینه‌ی مشاهده‌ی مداوم تغییرات که به صورت پیش فرض خاموش است. 
 progress--     نمایش جزئیات کامپایل و اجرای آزمون‌های واحد که به صورت پیش فرض فعال است. 
 sourcemaps--  sm-   تولید فایل‌های سورس‌مپ که به صورت پیش فرض فعال است. 
 watch--
 w-   بررسی مداوم تغییرات فایل‌ها و اجرای آزمون‌های واحد به صورت خودکار که به صورت پیش فرض فعال است. 

بنابراین اجرا دستور ng test بدون ذکر هیچ گزینه‌ای به معنای اجرای مداوم آزمون‌های واحد، در صورت مشاهده‌ی تغییراتی در آن‌ها، به کمک Karma است.
همچنین دو دستور ذیل نیز به یک معنا هستند و هر دو سبب یکبار اجرای آزمون‌های واحد می‌شوند:
> ng test -sr
> ng test -w false


اجرای بررسی میزان پوشش آزمون‌های واحد

یکی از گزینه‌های ng test روشن کردن پرچم code-coverage است:
 > ng test --code-coverage
برای آزمایش آن دستور ذیل را در ریشه‌ی پروژه اجرا کنید (که سبب اجرای یکبار برررسی میزان پوشش آزمون‌های واحد می‌شود):
 > ng test -sr -cc
پس از اجرای این آزمون ویژه، پوشه‌ی جدیدی به نام coverage در ریشه‌ی پروژه‌ی جاری تشکیل می‌شود. فایل index.html آن‌را در مرورگر باز کنید تا بتوان گزارش تولید شده را مشاهده کرد:


کار این آزمون بررسی قسمت‌های مختلف برنامه و ارائه گزارشی است که مشخص می‌کند آیا آزمون‌های واحد نوشته شده تمام انشعابات برنامه را پوشش می‌دهند یا خیر؟ برای مثال اگر در متدی if/else دارید، آیا فقط قسمت if را پوشش داده‌اید و یا آیا قسمت else هم در آزمون‌های واحد، بررسی شده‌است.


اجرای آزمون‌های end to end

هدف از ساخت یک برنامه ... استفاده‌ی از آن توسط دیگران است؛ اینجا است که آزمون‌های end to end مفهوم پیدا می‌کنند. در آزمون‌های e2e رفتار برنامه همانند حالتی که یک کاربر از آن استفاده می‌کند، بررسی می‌شود (برای مثال باز کردن مرورگر، لاگین و مرور صفحات). برای این منظور، Angular CLI  در پشت صحنه از Protractor برای این نوع آزمون‌ها استفاده می‌کند.  
برای مشاهده‌ی راهنما و گزینه‌های مختلف مرتبط با آزمون‌های e2e، می‌توان دستور ذیل را صادر کرد:
 >ng e2e --help
البته با توجه به اینکه این دستور کار توزیع برنامه را نیز انجام می‌دهد، تمام گزینه‌های ng serve نیز در اینجا صادق هستند، به علاوه‌ی موارد ذیل:

 گزینه  مخفف توضیح
 config--  c-   به فایل کانفیگ آزمون‌های e2e اشاره می‌کند که به صورت پیش‌فرض همان protractor.conf.js واقع در ریشه‌ی پروژه‌است. 
 element-explorer--  ee-   بررسی و دیباگ protractor از طریق خط فرمان 
 serve--  s-   کامپایل و توزیع برنامه بر روی پورتی اتفاقی (حالت پیش فرض آن true است) 
 specs--  sp-   پیش فرض آن بررسی تمام specهای موجود در پروژ‌ه‌است. اگر نیاز به لغو آن باشد می‌توان از این گزینه استفاده کرد. 
 webdriver-update--  wu- به روز رسانی web driver که به صورت پیش فرض فعال است. 

بنابراین زمانیکه دستور ng e2e صادر می‌شود، به معنای کامپایل، توزیع برنامه بر روی پورتی اتفاقی و اجرای آزمون‌ها است.

از این جهت که این نوع آزمون‌ها، وابسته‌ی به جزئی خاص از برنامه نیستند، حالت عمومی داشته و فایل‌های spec آن‌ها را می‌توان در پوشه‌ی e2e واقع در ریشه‌ی پروژه، یافت. برای مثال در قسمتی از آن کار یافتن متن نمایش داده شده‌ی در صفحه‌ی اول سایت انجام می‌شود
getParagraphText() {
    return element(by.css('app-root h1')).getText();
}
و سپس در فایل spec آن بررسی می‌کند که آیا مساوی app works هست یا خیر؟
 expect(page.getParagraphText()).toEqual('app works!');

برای آزمایش آن دستور ng e2e را در ریشه‌ی پروژه صادر کنید. همچنین دقت داشته باشید که در این حالت نیاز است به اینترنت نیز متصل باشد؛ چون از chromedriver api گوگل نیز استفاده می‌کند. در غیراینصورت خطای ذیل را دریافت خواهید کرد:
 Error: getaddrinfo ENOTFOUND chromedriver.storage.googleapis.com chromedriver.storage.googleapis.com:443