Cypress 中的非同步特性


Cypress 基於 node.js 伺服器構建,並使用 Javascript 程式語言。任何依賴於 node.js 的內容本質上都是非同步的,因此 Cypress 命令也以這種模式工作。

當我們在測試用例中有一組測試步驟時,所有步驟都會並行開始執行,而不會等待前一個步驟完成。在同步執行中,每個測試步驟按順序執行,只有在前一個步驟執行完成後,我們才會進入下一步。

因此,在像 Cypress 這樣的非同步執行中,即使測試步驟是按順序設計的,每個測試步驟也都是相互獨立的。簡而言之,在非同步模式下,每個步驟都不會考慮前一個步驟執行的結果或狀態,而只是簡單地執行每個步驟。

Cypress 提供了一個包裝器,確保其命令的測試執行按照開發順序發生。因此,這些命令會同時執行,但它們會被排隊。但是,如果 Javascript 命令與 Cypress 命令一起工作,它仍然是非同步的。

示例

現在讓我們執行一段 Cypress 程式碼:

// test suite
describe('Tutorialspoint Test', function () {
   // test case
   it('Test Case1', function (){
      // test step to launch a URL
      cy.visit("https://tutorialspoint.tw/index.htm");
      // enter test in the edit box
      cy.get('#gs_50d > tbody > tr > td'). should('have.length',2);
      // locate element with get and find method
      cy.get('#gs_50d > tbody > tr > td'). find('input')
      //enter test in the edit box
      .type('Cypress');
      console.log('Tutorialspoint');
   });
});

在觸發上述程式碼執行時,如果我們開啟瀏覽器控制檯,我們會在瀏覽器載入之前就發現 Tutorialspoint 列印在上面。這證實了 console.log 測試步驟沒有等待其他測試步驟,並立即在控制檯中列印。

因此,我們看到,由於 console.log 是一個 Javascript 命令,它不會像 Cypress 複合命令那樣進行排隊,而是繼續執行。Cypress 透過 promise 處理來順序執行其步驟。

Promise 是一種程式語言,用於確定 Cypress 命令的狀態。Promise 有三種狀態,如下所示:

  • 已解決(Resolved) - 如果測試步驟執行沒有失敗,則處於此狀態。

  • 掛起(Pending) - 如果正在等待測試步驟執行結果,則處於此狀態。

  • 已拒絕(Rejected) - 如果測試步驟執行失敗,則處於此狀態。

只有在前一個命令或 promise 響應已解決後,Cypress 中的以下命令才會執行。我們可以使用 then() 方法在 Cypress 程式碼中實現 promise。

示例

以下程式碼描述了在 Javascript 中為每個 Cypress 複合命令實現的 promise。這種實現使程式碼變得混亂且冗長。

// test suite
describe('Tutorialspoint Test', function () {
   // test case
   it('Test Case1', function (){
      return cy.visit('https://tutorialspoint.tw/index.htm')
      .then(() => {
         return cy.get('.product');
      })
      .then(($element) => {
         return cy.click($element);
      })
   })
})

Cypress 在內部處理 promise,並藉助包裝器來解決它們,我們可以實現我們的程式碼而無需考慮 promise 的狀態。因此,程式碼的可讀性大大提高。

上述 Cypress 程式碼,不使用 promise。

// test suite
describe('Tutorialspoint Test', function () {
   // test case
   it('Test Case1', function (){
      cy.visit('https://tutorialspoint.tw/index.htm')
      cy.get('.product').click();
   })
})

因此,Cypress 會考慮到測試用例中的下一步只有在前一個命令或 promise 處於已解決狀態時才會執行。

更新於: 2020年8月5日

351 次瀏覽

啟動您的 職業生涯

透過完成課程獲得認證

開始學習
廣告

© . All rights reserved.