تست های واحد، تست های واحد، تست های واحد، تست های واحد

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

دو مجموعه تست واحد وجود دارد: تست های JS و تست های مولد بلوک.

تست های JS

تست‌های JS عملکرد توابع جاوا اسکریپت داخلی در هسته Blockly را تایید می‌کنند. ما از Mocha برای اجرای تست‌های واحد، Sinon برای وابستگی‌های خرد و Chai برای اظهارنظر در مورد کد استفاده می‌کنیم.

در حال اجرا تست ها

در هر دو نمونه بلوکی و بلوکی، npm run test تست های واحد را اجرا می کند. در بلاکی، این تست های دیگری مانند لینتینگ و کامپایل را نیز اجرا می کند. همچنین می توانید tests/mocha/index.html در مرورگر باز کنید تا به صورت تعاملی تمام تست های موکا را اجرا کنید.

تست های نوشتاری

ما از رابط Mocha TDD برای اجرای تست ها استفاده می کنیم. آزمون‌ها در مجموعه‌هایی سازمان‌دهی می‌شوند که می‌توانند شامل مجموعه‌های فرعی و/یا تست‌های اضافی باشند. به طور کلی، هر مؤلفه Blockly (مانند toolbox یا workspace ) فایل آزمایشی خود را دارد که شامل یک یا چند مجموعه است. هر مجموعه می تواند یک روش setup و teardown داشته باشد که به ترتیب قبل و بعد از هر تست در آن مجموعه فراخوانی می شود.

یاوران تست

ما تعدادی توابع کمکی مخصوص Blockly داریم که ممکن است هنگام نوشتن تست ها مفید باشند. این ها را می توان در نمونه های هسته ای و بلوکی یافت.

توابع کمکی شامل sharedTestSetup و sharedTestTeardown هستند که لازم است قبل و بعد از آزمایش شما فراخوانی شوند (به بخش الزامات مراجعه کنید).

sharedTestSetup :
  • تایمرهای جعلی sinon را تنظیم می کند (در برخی آزمایشات باید از this.clock.runAll استفاده کنید).
  • Stubs Blockly.Events.fire برای شلیک فوری (قابل تنظیم).
  • پاکسازی خودکار blockType های تعریف شده توسط defineBlocksWithJsonArray را تنظیم می کند.
  • چند ویژگی در this زمینه را که قرار است در دسترس باشد، اعلام می کند:
    • this.clock (اما نباید بازیابی شود در غیر این صورت باعث بروز مشکلاتی در sharedTestTeardown می شود)
    • this.eventsFireStub
    • this.sharedCleanup (برای استفاده با addMessageToCleanup و addBlockTypeToCleanup ) (توجه: اگر بلوک را با استفاده از defineBlocksWithJsonArray تعریف کرده اید، نیازی به استفاده از addBlockTypeToCleanup ندارید)

این تابع دارای یک پارامتر options اختیاری برای پیکربندی تنظیمات است. در حال حاضر، فقط برای تعیین اینکه آیا Blockly.Events.fire را به‌طور فوری فعال کنیم یا نه (به طور پیش‌فرض خرد خواهد شد) استفاده می‌شود.

sharedTestTeardown :
  • فضای کاری this.workspace را از بین می برد (بسته به جایی که تعریف شده است، برای اطلاعات بیشتر به بخش نیازمندی های تست مراجعه کنید).
  • همه خردها را بازیابی می کند.
  • تمام انواع بلوک های اضافه شده را با استفاده از defineBlocksWithJsonArray و addBlockTypeToCleanup پاک می کند.
  • همه پیام‌های اضافه شده را با addMessageToCleanup پاک می‌کند.

الزامات آزمون

  • هر آزمون باید sharedTestSetup.call(this); به عنوان اولین خط در راه اندازی بیرونی ترین مجموعه و sharedTestTeardown.call(this); به‌عنوان آخرین خط در حذف بیرونی‌ترین مجموعه برای یک فایل.
  • اگر به یک فضای کاری با جعبه ابزار عمومی نیاز دارید، می توانید از یکی از جعبه ابزارهای از پیش تعیین شده در test index.html استفاده کنید. برای مثال زیر را ببینید.
  • شما باید this.workspace را به درستی از بین ببرید. در اکثر تست‌ها، this.workspace در بیرونی‌ترین مجموعه تعریف می‌کنید و از آن برای همه آزمایش‌های بعدی استفاده می‌کنید، اما در برخی موارد ممکن است آن را در یک مجموعه داخلی تعریف یا دوباره تعریف کنید (برای مثال، یکی از آزمایش‌های شما به فضای کاری با گزینه‌های مختلف نیاز دارد. از آنچه که در ابتدا تنظیم کرده بودید). در پایان آزمایش باید دور ریخته شود.
    • اگر this.workspace در بیرونی ترین مجموعه تعریف کنید و هرگز آن را دوباره تعریف نکنید، نیازی به اقدام بیشتری نیست. به طور خودکار توسط sharedTestTeardown حذف خواهد شد.
    • اگر this.workspace برای اولین بار در یک مجموعه داخلی تعریف می کنید (یعنی آن را در بیرونی ترین مجموعه تعریف نکرده اید)، باید به صورت دستی آن را با فراخوانی workspaceTeardown.call(this, this.workspace) در حذف آن حذف کنید. سوئیت
    • اگر this.workpace در بیرونی ترین مجموعه تعریف کنید، اما سپس آن را در یک مجموعه آزمایشی داخلی دوباره تعریف کنید، ابتدا باید workspaceTeardown.call(this, this.workspace) قبل از تعریف مجدد آن برای از بین بردن فضای کاری اصلی تعریف شده در مجموعه سطح بالا فراخوانی کنید. . همچنین باید با فراخوانی مجدد workspaceTeardown.call(this, this.workspace) در قسمت حذفی این مجموعه داخلی، مقدار جدید را به صورت دستی از بین ببرید.

ساختار تست

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

  1. ترتیب : وضعیت جهان و هر شرایط لازم برای رفتار تحت آزمایش را تنظیم کنید.
  2. Act : کد تحت آزمایش را فراخوانی کنید تا رفتار مورد آزمایش را فعال کند.
  3. ادعا : در مورد مقدار بازگشتی یا تعامل با اشیاء مسخره شده اظهار نظر کنید تا صحت را تأیید کنید.

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

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

suite('Flyout', function() {
  setup(function() {
    sharedTestSetup.call(this);
    this.toolboxXml = document.getElementById('toolbox-simple');
    this.workspace = Blockly.inject('blocklyDiv',
        {
          toolbox: this.toolboxXml
        });
  });

  teardown(function() {
    sharedTestTeardown.call(this);
  });

  suite('simple flyout', function() {
    setup(function() {
      this.flyout = this.workspace.getFlyout();
    });
    test('y is always 0', function() {
      // Act and assert stages combined for simple test case
      chai.assert.equal(this.flyout.getY(), 0, 'y coordinate in vertical flyout is 0');
    });
    test('x is right of workspace if flyout at right', function() {
      // Arrange
      sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
        viewWidth: 100,
      });
      this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_RIGHT;
      this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_RIGHT;

      // Act
      var x = this.flyout.getX();

      // Assert
      chai.assert.equal(x, 100, 'x is right of workspace');
    });
  });
});

نکاتی که باید از این مثال توجه کرد:

  • یک مجموعه می‌تواند شامل مجموعه‌های دیگری باشد که روش‌های setup و teardown اضافی دارند.
  • هر مجموعه و آزمون یک نام توصیفی دارد.
  • اظهارات Chai برای اظهار نظر در مورد کد استفاده می شود.
    • شما می توانید یک آرگومان رشته اختیاری ارائه کنید که در صورت شکست تست نمایش داده می شود. این باعث می‌شود تا اشکال‌زدایی تست‌های شکسته را آسان‌تر کنید.
    • ترتیب پارامترها chai.assert.equal(actualValue, expectedValue, optionalMessage) است. اگر actual و expected را تعویض کنید، پیام های خطا معنی نخواهند داشت.
  • زمانی که نمی خواهید کد واقعی را فراخوانی کنید از سینون برای خرد کردن متدها استفاده می شود. در این مثال، ما نمی‌خواهیم تابع متریک واقعی را فراخوانی کنیم زیرا به این تست مربوط نیست. ما فقط به نحوه استفاده از نتایج توسط روش مورد آزمایش اهمیت می دهیم. Sinon تابع getMetrics را برای بازگرداندن یک پاسخ آماده می کند که می توانیم به راحتی آن را در اظهارات آزمایشی خود بررسی کنیم.
  • روش‌های setup برای هر مجموعه باید فقط شامل تنظیمات عمومی باشد که برای همه آزمایش‌ها اعمال می‌شود. اگر آزمونی برای یک رفتار خاص متکی به شرایط خاصی باشد، آن شرط باید به وضوح در آزمون مربوطه بیان شود.

تست های اشکال زدایی

  • می‌توانید تست‌ها را در یک مرورگر باز کنید و از ابزارهای توسعه‌دهنده برای تعیین نقاط شکست استفاده کنید و بررسی کنید که آیا تست‌های شما به طور غیرمنتظره شکست خورده‌اند (یا به طور غیرمنتظره قبول شده‌اند!).
  • .only() یا .skip() روی یک تست یا مجموعه تنظیم کنید تا فقط آن مجموعه از تست ها اجرا شود، یا از یک تست صرفنظر کنید. به عنوان مثال:

    suite.only('Workspace', function () {
      suite('updateToolbox', function () {
        test('test name', function () {
          // ...
        });
        test.skip('test I don’t care about', function () {
          // ...
        });
      });
    });
    

    به یاد داشته باشید که قبل از اجرای کد خود، این موارد را حذف کنید.

تست های بلاک ژنراتور

هر بلوک تست های واحد خود را دارد. این تست‌ها تأیید می‌کنند که بلوک‌ها کد تولید می‌کنند تا توابع مورد نظر.

  1. tests/generators/index.html را در فایرفاکس یا سافاری بارگیری کنید. توجه داشته باشید که Chrome و Opera دارای محدودیت‌های امنیتی هستند که از بارگیری آزمایش‌ها از سیستم محلی "file://" جلوگیری می‌کند (نسخه‌های 41024 و 47416 ).
  2. قسمت مربوطه از سیستم را برای آزمایش از منوی کشویی انتخاب کنید و روی "بارگیری" کلیک کنید. بلوک ها باید در فضای کاری ظاهر شوند.
  3. بر روی "جاوا اسکریپت" کلیک کنید.
    کد تولید شده را در یک کنسول جاوا اسکریپت کپی و اجرا کنید. اگر خروجی با "OK" خاتمه یابد، آزمون قبول شده است.
  4. روی "Python" کلیک کنید.
    کد تولید شده را در یک مفسر پایتون کپی و اجرا کنید. اگر خروجی با "OK" خاتمه یابد، آزمون قبول شده است.
  5. روی "PHP" کلیک کنید.
    کد تولید شده را در یک مفسر PHP کپی و اجرا کنید. اگر خروجی با "OK" خاتمه یابد، آزمون قبول شده است.
  6. روی "Lua" کلیک کنید.
    کد تولید شده را در مترجم Lua کپی و اجرا کنید. اگر خروجی با "OK" خاتمه یابد، آزمون قبول شده است.
  7. روی "دارت" کلیک کنید.
    کد تولید شده را در یک مفسر دارت کپی و اجرا کنید. اگر خروجی با "OK" خاتمه یابد، آزمون قبول شده است.

ویرایش تست های بلاک مولد

  1. بارگذاری tests/generators/index.html در مرورگر.
  2. قسمت مربوطه از سیستم را از منوی کشویی انتخاب کنید و روی "بارگیری" کلیک کنید. بلوک ها باید در فضای کاری ظاهر شوند.
  3. هر گونه تغییر یا اضافات را در بلوک ها ایجاد کنید.
  4. روی "XML" کلیک کنید.
  5. XML تولید شده را در فایل مناسب در tests/generators/ کپی کنید.