iT邦幫忙

2022 iThome 鐵人賽

DAY 20
2
Modern Web

今天我想來在 Angular 應用程式上加上測試保護系列 第 20

Day 20 - 端對端測試 - 利用 Cypress 描述使用者操作

  • 分享至 

  • xImage
  •  

前言

上一篇說明了 Cypress 框架提供的描述與群組化測試案例,以及生命週期鉤子的方法。而在 Cypress 內整合了多種的斷言 (Assertions) 方法,這一篇會說明如何這些 API 來描述使用者操作流程。

常用斷言 (Assertions) 方法

載入特定網址

如先前文章提到,端點端測試是從使用者操作的角度進行測試,而一開始我們可以利用下列語法來載入要測試的頁面。

cy.visit(url);

在測試的驗證方法,Cypress 提供了預設的斷言,讓我們可以不用明確地指定每個動作的預期結果,visit() 就是預設的斷言方法之一。另外,此方法所傳入的網址會以 cypress.config.ts 組態檔內的 baseUrl 參數為根路由。

export default defineConfig({
  e2e: {
    baseUrl: 'http://localhost:4200',
  },
});

如上面設定,在範例程式中將 baseUrl 設定為 http://localhost:4200, 因此,在 application.cy.ts 測試檔案內,一開始使用 visit('/') 來載入範例程式的首頁。

describe('2022 鐵人賽範例', () => {
  beforeEach(() => {
    cy.visit('/');
  });
});

取得瀏覽器載入路徑

在應用程式切換頁面時,我們可以利用 Cypress 提供的 url() 來取得當下的網址,進一步去驗證是否截入預期的網頁路徑。

cy.url()

取得瀏覽標題文字

同樣的,Cypress 提供了 title() 來讓我們取得瀏覽器上所顯示的標題文字。

cy.title()

取得頁面元素

Cypress 提供了兩種方法讓我們可以取得 DOM 元素。首先可以利用 contains() 方法取得頁面元素:

cy.contains(content);
cy.contains(content, options)
cy.contains(selector, content)
cy.contains(selector, content, options)

這個方法可以取得頁面元素內容與傳入的 content 字串相同的 DOM 元素。例如在 app.component.html 範本程式內,我們指定了應用程式標題列文字為「2022 鐵人賽範例」。

<mat-toolbar color="primary">
  <span class="title">2022 鐵人賽範例</span>
  ...
</mat-toolbar>

我們就可以利用下面程式,來取得與驗證此標題文字是否正確。

it('顯示標題為 "2022 鐵人賽範例"', () => {
  cy.contains('2022 鐵人賽範例');
});

這個方法也可以傳入 CSS 選擇器來限縮找尋的範團;因此,上面的測試案例我們也可以寫成:

it('顯示標題為 "2022 鐵人賽範例"', () => {
  cy.contains('.title', '2022 鐵人賽範例');
});

其次,我們也可以利用 get() 方法來依 CSS 選擇器取得頁面上的 DOM 元素。

cy.get(selector)
cy.get(selector, options)

例如上面取得標題列文字的範例,也可以改寫成:

it('顯示標題為 "2022 鐵人賽範例"', () => {
  cy.get('.title').contains('2022 鐵人賽範例');
});

如上面程式,利用 get() 方法來取得 .title 選擇器,接續著 contains() 方法來驗證標題文字的正確性。

不過利用此方法可能會取得的多個 DOM 元素,除了可以利用 :first 這類型的 CSS 選擇器取得所要的對象,也可以利用 Cypress 裡的 eq() 方法,來指定目標 DOM 元素。

.eq(index)
.eq(indexFromEnd)
.eq(index, options)
.eq(indexFromEnd, options)

例如,我們要驗證「點選完登入按鈕時,應轉至登入頁面」,需要先取得到頁面上的按鈕,就可以利用下面程式來取得按鈕元素。

it('當點選登入按鈕, 應轉至登入頁面', () => {
  cy.get('button.mat-icon-button').eq(1).click();
  ...
});

eq() 方法也可以傳入負值,因此我們也可指定成 -1 來取得最後一個按鈕元素:

it('當點選登入按鈕, 應轉至登入頁面', () => {
  cy.get('button.mat-icon-button').eq(-1).click();
  ...
});

輸入使用者表單

如上面點選登入按鈕範例,在 Cypress 裡會使用 click() 方法來點選頁面上的按鈕,若要輸入表單則會使用下面方法:

  • type() - 文字框 (input / textarea ) 輸入
  • clear() - 文字框 (input / textarea ) 內容清除
  • select() - 下拉選單 (select) 選擇
  • check() - 單選 (radio) 與多選 (checkbox) 項目選擇
  • uncheck() - 多選 (checkbox) 項目取消選擇
  • selectFile() - 選擇欲上傳的檔案
it('當輸入不存在帳號, 應顯示錯誤訊息', () => {
  cy.get('button.mat-icon-button').contains('login').click();
  cy.get('input[type=text]').type('userB').blur();
  cy.contains('帳號不可為空白').should('not.exist');
  cy.get('button').should('be.disabled');
});

上面測試程式,就在進入登入頁面後,利用 type() 方法輸入使用者帳號,以驗證是否在帳號不存在時,是否有顯示應有的錯誤訊息。順在一提,在此因 Angular Material 錯誤訊息是在離開焦點後顯示,所以在輸入完後利用 blur() 來離開焦點。

接下來

今天介紹了 Cypress 裡提供的斷言方法,完整的測試程式可以參考 GitHub。接下來,明天會說明如何在 Cypress 明確指定所需要驗證的事項。


上一篇
Day 19 - 端對端測試 - 利用 Cypress 撰寫測試案例
下一篇
Day 21 - 端對端測試 - 利用 Cypress 驗證應用程式
系列文
今天我想來在 Angular 應用程式上加上測試保護30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言