如昨天文章所言,我們可以利用 Cypress 所提供的預設斷言來驗證應用程式執行的狀況。這一篇則來說明如何利用 Cypress 的 should()
方法驗證應用程式。
should()
驗證應用程式.should(chainers)
.should(chainers, value)
.should(chainers, method, value)
.should(callbackFn)
在 Cypress 的 should()
方法中,整合了 Chai、Chai-jQuery 與 Sinon-Chai 函式庫裡的斷言,來驗證應用程式執行的過程是否符合預期,常用的有:
當我們取得頁面元素的內容文字時,我們可以利用 eq
來與預期值進行相等的比較,例如,在 application.cy.ts
裡,針對瀏覽器標題文字的驗證,就可以寫成:
it('顯示瀏覽器標題為 "2022 鐵人賽範例"', () => {
cy.title().should('eq', '2022 鐵人賽範例');
});
若要針對部份文字的驗證,則會使用 include
來進行。例如,在測試點選登入按鈕時,是否正確載入頁面,就可以驗證是否包含特定文字:
it('當點選登入按鈕, 應轉至登入頁面', () => {
cy.url().should('include', '/login');
});
順帶一提,如果需要針對物件進行驗證可以使用斷言之前加入 deep
,如 deep.eq
或 deep.include
。
如果我們要驗證在登入頁面中,當輸入的帳號不存在的時候,登入按鈕應被停用,就可以透過 be.disabled
來針對登入按鈕的停用狀態進行驗證。
it('當輸入不存在帳號, 應顯示錯誤訊息, 且無法按下登入按鈕', () => {
cy.get('button.mat-icon-button').contains('login').click();
cy.get('input[type=text]').type('userB').blur();
cy.get('button').contains('登入').parent().should('be.disabled');
});
實務上,常會需要在特定操作下,更換特定頁面元素的樣式。在撰寫 Cypress 端對端測試時,就可以利用 have.class
來驗證目標元素是否套件所預期的樣式。
it('當輸入不存在帳號, 應顯示錯誤訊息, 且無法按下登入按鈕', () => {
cy.get('button.mat-icon-button').contains('login').click();
cy.get('input[type=text]').type('userB').blur();
cy.get('button')
.contains('登入')
.parent()
.should('have.class', 'mat-button-disabled');
});
在上面程式中,因為 Angular Material 在被停用的按鈕套用上 mat-button-disabled
樣式,所以我們也可以驗證登入按鈕是否有套用此樣式。
同樣地,使用「帳號不存在」的測試案例,此時會需要出現對應的錯誤訊息,此時就會使用 exist
斷言來檢查錯誤訊息的頁面元素是否存在。
it('當輸入不存在帳號, 應顯示錯誤訊息, 且無法按下登入按鈕', () => {
cy.get('button.mat-icon-button').contains('login').click();
cy.get('input[type=text]').type('userB').blur();
cy.contains('此帳號不存在').should('exist');
});
除了上面驗證錯誤訊息是否存在之外,我們也可以利用 have.text
斷言來確認 MatError
頁面元素的文字內容是否為「此帳號不存在」。
it('當輸入不存在帳號, 應顯示錯誤訊息, 且無法按下登入按鈕', () => {
cy.get('button.mat-icon-button').contains('login').click();
cy.get('input[type=text]').type('userB').blur();
cy.get('mat-error').should('have.text', '此帳號不存在');
});
除此之外,也可以利用 include.text
或 contain
來檢查文字內容是否包含預期文字;更進一步,還可以利用 match
斷言來透過正規化字串驗證文字內容。
上面的斷言都是以正向的方式來做驗證,當需要做反向驗證的時候,如不存在、不包含等,可以在正向驗證前加入 not
即可;例如,我們要驗證登入按鈕是啟用,就可以寫成:
cy.get('button').contains('登入').parent().should('not.be.disabled');
有時候我們會需要針對同一個頁面元素進行多個不同的驗證,這時候就可以利用 Cypress 提供的 and()
來把要驗證的事項串連在一起。例如在「帳號不存在」的測試案例,我們可以在檢查錯誤訊息內容前,先確認 MatError
是否存在,那就可以寫成:
it('當輸入不存在帳號, 應顯示錯誤訊息, 且無法按下登入按鈕', () => {
cy.get('button.mat-icon-button').contains('login').click();
cy.get('input[type=text]').type('userB').blur();
cy.get('mat-error').should('exist').and('have.text', '此帳號不存在');
});
expect
驗證應用程式從一開始的 should()
方法簽章中可以看到,其也接收傳入一個方法,我們可以透過這個方法來針對目標元素,進行多種不同的驗證。
it('當輸入不存在帳號, 應顯示錯誤訊息, 且無法按下登入按鈕', () => {
cy.get('button.mat-icon-button').contains('login').click();
cy.get('input[type=text]').type('userB').blur();
cy.get('mat-error').should((target) => {
expect(target).to.exist;
expect(target).to.have.text('此帳號不存在');
});
});
如上面程式,在傳入的方法中,會使用 expect()
方法來針對頁面進行是否存在與錯誤訊息文字的驗證。
今天介紹了在 Cypress 驗證的撰寫方式,完整的測試程式可以參考 GitHub。接下來,會來說明 Cypress 提供的 Fixture 來組織測試案例資料,以及如何設定環境變數。