單元測試

變更或新增程式碼後,您應執行現有的單元測試,並考慮編寫更多測試。所有測試都會在未壓縮的程式碼版本上執行。

單元測試分為兩種:JS 測試和區塊產生器測試。

JS 測試

JS 測試可確認 Blockly 的 核心指標。我們使用 Mocha 執行單元測試,使用 Sinon 模擬依附元件,並使用 Chai 對程式碼做出斷言。

執行測試

在 Blockly 和 Blockly 範例中,npm run test 會執行單元測試。於 這樣做也會執行其他測試,例如程式碼檢查和編譯。你可以 也會在瀏覽器中開啟 tests/mocha/index.html,以互動方式執行所有 Mocha 測試。

撰寫測試

我們使用 Mocha TDD 介面執行測試。測試會歸入套件,套件可包含其他子套件和/或測試。一般而言 Blockly 的元件 (例如 toolboxworkspace) 有專屬的測試檔案 當中包含一或多個套房每個套件都可以有 setupteardown 方法,分別在該套件中每項測試之前和之後呼叫。

測試輔助程式

我們為 Blockly 推出許多專用輔助函式 以及編寫測試您可以在 coreblockly-samples 中找到這些元素。

輔助函式包含 sharedTestSetupsharedTestTeardown, 則在測試前後必須呼叫 (詳情請參閱相關規定 部分)。

sharedTestSetup
  • 設定 Sinon 假計時器 (在某些測試中,您需要使用 this.clock.runAll)。
  • 模擬 Blockly.Events.fire 立即觸發 (可設定)。
  • 設定自動清理已定義的 blockType defineBlocksWithJsonArray
  • this 結構定義中宣告幾個要定義的屬性 可存取:
    • this.clock (但不應還原,否則會導致以下項目發生問題: sharedTestTeardown)
    • this.eventsFireStub
    • this.sharedCleanup (適用於 addMessageToCleanupaddBlockTypeToCleanup) (注意:您不必使用 如果使用 addBlockTypeToCleanup 定義區塊 defineBlocksWithJsonArray)

這個函式有一個選用 options 參數,可用於設定設定。目前,它只用於判斷是否要立即觸發 Blockly.Events.fire 的虛設項目 (預設會觸發虛設項目)。

sharedTestTeardown
  • 處置工作區 this.workspace (視定義位置而定, 詳情請參閱「測試規定」一節)。
  • 還原所有虛設常式。
  • 清除透過 defineBlocksWithJsonArrayaddBlockTypeToCleanup
  • 清除透過 addMessageToCleanup 新增的所有訊息。

測試規定

  • 每個測試都必須在最外層套件的設定中,以第一行呼叫 sharedTestSetup.call(this);,並在檔案最外層套件的拆解中,以最後一行呼叫 sharedTestTeardown.call(this);
  • 如果工作區需要使用一般工具箱,可以使用 預設工具箱 測試 index.html。請參閱以下範例。
  • 請務必妥善處理 this.workspace。在大多數測試中 在最外的套件中定義 this.workspace,並將其用於所有後續的套件 但在某些情況下,您可能會在內部套件中 (舉例來說,您的其中一項測試需要一個含有不同選項的工作區 而不是最初的設定)。必須在測試結束時丟棄。
    • 如果您在最外套套件中定義 this.workspace,且從未重新定義 則不需要採取進一步行動系統會自動將其移除。
    • 如果您在內部套件中首次定義 this.workspace (也就是未在最外層套件中定義),則必須在該套件的拆解作業中呼叫 workspaceTeardown.call(this, this.workspace),才能手動處置。
    • 如果您在最外層套件中定義 this.workpace,但在內部測試套件中重新定義,則必須先呼叫 workspaceTeardown.call(this, this.workspace)再重新定義,才能拆除在頂層套件中定義的原始工作區。個人中心 您也必須呼叫 workspaceTeardown.call(this, this.workspace)再次進入下一局 這個內部套件

測試結構

單元測試通常會遵循固定的結構,這可以總結為 編排、行動、斷言

  1. Arrange:設定世界狀態,以及 受測試的行為
  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');
    });
  });
});

這個範例的注意事項:

  • 套房可能包含其他具有額外 setupteardown 的套件 方法。
  • 每個套件和測試都有描述性名稱。
  • Chai 斷言可用於對程式碼做出斷言。
    • 您可以提供選用的字串引數,在測試失敗時顯示該字串。這樣可更輕鬆地對損壞的測試進行偵錯。
    • 參數的順序為 chai.assert.equal(actualValue, expectedValue, optionalMessage)。如果您交換 actualexpected,錯誤訊息就會變得毫無意義。
  • 如果您不想呼叫實際程式碼,可使用 Sinon 虛設常式方法。於 也不想要呼叫實際指標函式 與這項測試無關我們只關心系統如何使用結果 測試受測試的方法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. 在 Firefox 或 Safari 中載入 tests/generators/index.html。請注意,Chrome 和 Opera 設有安全性限制,可防止從本機「file://」系統載入測試 (問題 4102447416)。
  2. 從下拉式選單中選擇要測試的系統部分,然後 按一下「載入」工作區中應該會顯示區塊。
  3. 按一下「JavaScript」。
    在 JavaScript 控制台中複製並執行產生的程式碼。如果輸出內容結束 「OK」則表示測試已通過。
  4. 按一下「Python」。
    Python 解譯器中複製並執行產生的程式碼。如果輸出內容結尾為「OK」,表示測試已通過。
  5. 按一下「PHP」。
    PHP 解譯器中複製及執行產生的程式碼。 如果輸出內容結尾為「OK」,表示測試已通過。
  6. 按一下「Lua」。
    複製並在 Lua 解譯器中執行產生的程式碼。如果輸出內容結尾為「OK」,表示測試已通過。
  7. 按一下「Dart」。
    複製並在 Dart 解譯器中執行產生的程式碼。如果輸出內容的結尾是「OK」,表示測試已通過。

編輯區塊產生器測試

  1. 在瀏覽器中載入 tests/generators/index.html
  2. 從下拉式選單中選擇系統的相關部分,然後按一下 「載入」。區塊應會顯示在工作區中。
  3. 對區塊做出變更或新增內容。
  4. 按一下「XML」。
  5. 將產生的 XML 複製到 tests/generators/ 中的適當檔案。