iT邦幫忙

2023 iThome 鐵人賽

0
自我挑戰組

用ChatGPT詠唱來完成工作與點亮前後端技能樹系列 第 33

【Day33】ChatGPT請教教我:E2E測試!Cypress!(中)- Cypress 完整語法

  • 分享至 

  • xImage
  •  

經歷了上個章節的安裝,總之是先將Cypress的環境給建置起來了
接下來這個章節要來探討Cypress的寫法與語法

所謂的e2e測試到底是怎麼運作起來的呢?
我們來Go Go

Cypress 概念 & 語法總覽

https://ithelp.ithome.com.tw/upload/images/20231015/20135750qclECel5xG.png

當然沒問題!首先,讓我來為你介紹一下 Cypress 測試的基本概念。

Cypress 測試概念介紹

Cypress 是一個前端自動化測試工具,它主要用於測試網頁應用程式。以下是一些基本概念:

1. Specs (規格)

Cypress 的測試程式碼通常被稱為 "specs"。一個 spec 檔案通常對應到你要測試的一個功能或者一個頁面。

2. Describe 和 It

在 Cypress 中,你會使用 describeit 來組織你的測試程式碼。describe 用於定義一個測試套件,而 it 用於定義一個具體的測試案例。

範例:

describe('登入頁面測試', () => {
  it('應該顯示正確的登入畫面', () => {
    // 測試程式碼寫在這裡
  });
});

3. Selectors (選擇器)

你會使用 Cypress 的選擇器來選取你要進行測試的元素,就像 jQuery 中的 $ 一樣。

範例:

cy.get('.login-btn').click();

4. Commands (指令)

Cypress 提供了許多內建的指令來進行操作,比如 clicktypevisit 等等。

範例:

cy.visit('https://www.example.com');

5. Assertions (斷言)

你可以使用 shouldexpect 來斷言你的應用程式的狀態。

範例:

cy.get('.username').should('have.value', 'john_doe');

Cypress 語法完整教學

現在讓我為你提供一個完整的 Cypress 測試程式碼範例,假設你要測試一個簡單的登入頁面:

describe('登入頁面測試', () => {
  it('應該顯示正確的登入畫面', () => {
    // 前往登入頁面
    cy.visit('https://www.example.com/login');

    // 驗證是否有正確的標題
    cy.get('h1').should('contain', '登入');

    // 輸入帳號和密碼
    cy.get('.username').type('john_doe');
    cy.get('.password').type('password123');

    // 點擊登入按鈕
    cy.get('.login-btn').click();

    // 驗證是否成功登入
    cy.url().should('eq', 'https://www.example.com/dashboard');
    cy.get('.welcome-message').should('contain', '歡迎回來,John Doe!');
  });
});

這是一個簡單的 Cypress 測試,它前往登入頁面,輸入帳號和密碼,然後點擊登入按鈕,最後驗證是否成功登入。

希望這份教學對你有所幫助!如果你有任何問題或需要進一步的說明,請隨時告訴我。

上面的範例程式碼,因為用的是https://www.example.com/login 這個假網址
這個網址下實際上沒有任何登入介面、欄位、按鈕
所以直接拿起來跑會失敗的,無法進行他所預期的操作
先簡單看過這份範例,我們針對他所列出的個項來深入了解

Specs、Describe 和 It

https://ithelp.ithome.com.tw/upload/images/20231015/201357501kJt36qosS.png

當然,讓我為你提供更詳細的介紹和完整教學:

Specs (規格)

在 Cypress 中,spec 是指測試程式碼所屬的檔案,通常以 .spec.js.spec.ts 結尾。每個 spec 檔案通常專注於測試一個特定的功能、頁面或元件。

例如,如果你要測試一個登入頁面,你可以創建一個名為 login.spec.js 的檔案。

Describe 和 It

describeit 是 Mocha 測試框架提供的函式,它們用於組織你的測試程式碼。

describe

describe 用於定義一個測試套件,通常用於描述一個功能或一個頁面。一個 spec 檔案通常會包含多個 describe 塊,每個 describe 塊可以包含多個 it 塊。

describe('登入頁面測試', () => {
  // 測試程式碼寫在這裡
});

it

it 用於定義一個具體的測試案例,通常用於描述一個特定的行為或檢查一個特定的情況。

describe('登入頁面測試', () => {
  it('應該顯示正確的登入畫面', () => {
    // 測試程式碼寫在這裡
  });
});

一個 it 塊通常包含測試程式碼和一個描述(字串),描述會顯示在測試結果報告中。

完整教學範例

讓我們以一個具體的範例來說明如何使用 describeit

describe('登入頁面測試', () => {
  it('應該顯示正確的登入畫面', () => {
    // Arrange (準備)
    cy.visit('https://www.example.com/login');

    // Act (操作)
    cy.get('.username').type('john_doe');
    cy.get('.password').type('password123');
    cy.get('.login-btn').click();

    // Assert (斷言)
    cy.url().should('eq', 'https://www.example.com/dashboard');
    cy.get('.welcome-message').should('contain', '歡迎回來,John Doe!');
  });

  it('應該顯示錯誤訊息', () => {
    // Arrange
    cy.visit('https://www.example.com/login');

    // Act
    cy.get('.username').type('invalid_username');
    cy.get('.password').type('invalid_password');
    cy.get('.login-btn').click();

    // Assert
    cy.get('.error-message').should('contain', '帳號或密碼錯誤');
  });
});

這個範例包含兩個測試案例,第一個測試確認在正確輸入帳號密碼後是否能成功登入,第二個測試確認在輸入錯誤的帳號密碼後是否會顯示錯誤訊息。

希望這份詳細的介紹和範例對你有所幫助!如果你有任何進一步的問題,請隨時告訴我。

和Jest很像,用it 來包住一個完整的測試,用describe 將測試分層分區,針對一樣的測試範圍的不同case組起來,讓測試結構看起來更完整、全面

Selectors (選擇器)

https://ithelp.ithome.com.tw/upload/images/20231015/20135750nM962VaUq9.png

當然,我將提供有關 Cypress 中的選擇器(Selectors)的詳細介紹和完整教學。

選擇器(Selectors)

在 Cypress 中,選擇器用於選取你要進行測試的網頁元素,就像在 jQuery 中使用 $ 來選取元素一樣。

以下是一些常用的選擇器:

1. 類別選擇器

類別選擇器使用 . 符號,後接元素的類別名稱。它會選取所有具有該類別的元素。

cy.get('.login-btn').click(); // 選取類別為 "login-btn" 的按鈕元素

2. ID 選擇器

ID 選擇器使用 # 符號,後接元素的 ID 名稱。它會選取具有該 ID 的元素(注意:在 HTML 文件中,ID 應該是唯一的)。

cy.get('#username').type('john_doe'); // 選取 ID 為 "username" 的輸入框元素

3. 元素選擇器

元素選擇器直接使用元素的名稱,例如 divbuttoninput 等。它會選取所有符合條件的元素。

cy.get('input[type="text"]').type('Hello World'); // 選取所有 type 為 "text" 的輸入框元素

4. 複合選擇器

你可以結合不同的選擇器來定位元素。例如,選取一個特定的類別下的元素:

cy.get('.container .login-btn').click(); // 選取類別為 "container" 下的類別為 "login-btn" 的按鈕元素

5. 子元素選擇器

你可以使用 > 符號來選取子元素。例如,選取某個元素下的子元素:

cy.get('.parent-element > .child-element').click(); // 選取 class 為 "parent-element" 下的 class 為 "child-element" 的元素

6. 屬性選擇器

你可以根據元素的屬性進行選擇。例如,選取擁有特定屬性的元素:

cy.get('[data-testid="submit-button"]').click(); // 選取具有 data-testid 屬性為 "submit-button" 的元素

完整教學範例

讓我們使用這些選擇器來寫一個簡單的 Cypress 測試:

describe('選擇器示例', () => {
  it('應該選取正確的元素', () => {
    cy.visit('https://www.example.com');

    // 類別選擇器
    cy.get('.login-btn').click();

    // ID 選擇器
    cy.get('#username').type('john_doe');

    // 元素選擇器
    cy.get('input[type="password"]').type('password123');

    // 複合選擇器
    cy.get('.container .submit-btn').click();

    // 子元素選擇器
    cy.get('.parent-element > .child-element').click();

    // 屬性選擇器
    cy.get('[data-testid="submit-button"]').click();
  });
});

這個範例演示了如何使用不同類型的選擇器來選取不同的元素進行操作。

希望這份教學對你有所幫助!如果你有任何進一步的問題,請隨時告訴我。

和單元測試不同的是,E2E測試因為要模擬「操作」

所以必須要能夠「選擇」到畫面上的元件、內容

再針對內容去做判斷或是指定的操作

Commands (指令)

https://ithelp.ithome.com.tw/upload/images/20231015/20135750xJ4spa8duu.png

當然,我將提供有關 Cypress 中指令的詳細介紹和完整教學。

Commands (指令)

在 Cypress 中,指令是用來執行各種動作或操作的方法。它們讓你能夠模擬使用者在網頁上的互動,例如點擊按鈕、輸入文字等。

以下是一些常用的 Cypress 指令:

1. cy.visit(url)

這個指令用於前往指定的網頁。

cy.visit('https://www.example.com'); // 前往指定網址

2. cy.get(selector)

這個指令用於選取網頁上的元素,你可以使用前面提到的選擇器來定位元素。

cy.get('.login-btn').click(); // 選取類別為 "login-btn" 的按鈕並點擊

3. cy.type(text)

這個指令用於在選取的輸入框中輸入文字。

cy.get('#username').type('john_doe'); // 在 ID 為 "username" 的輸入框中輸入文字

4. cy.click()

這個指令用於點擊選取的元素,通常用於按鈕或連結。

cy.get('.login-btn').click(); // 點擊類別為 "login-btn" 的按鈕

5. cy.contains(text)

這個指令用於選取包含指定文字的元素。

cy.contains('登入').click(); // 點擊包含文字 "登入" 的元素

6. cy.url()

這個指令用於獲取當前網址。

cy.url(); // 獲取當前網址

7. cy.should()

這個指令用於進行斷言,驗證特定條件是否成立。

cy.get('.welcome-message').should('contain', '歡迎回來,John Doe!'); // 驗證是否包含特定文字

完整教學範例

讓我們使用這些指令來寫一個簡單的 Cypress 測試:

describe('指令示例', () => {
  it('應該執行正確的操作', () => {
    cy.visit('https://www.example.com');

    cy.get('#username').type('john_doe');
    cy.get('input[type="password"]').type('password123');

    cy.contains('登入').click();

    cy.url().should('eq', 'https://www.example.com/dashboard');

    cy.get('.welcome-message').should('contain', '歡迎回來,John Doe!');
  });
});

這個範例演示了如何使用不同的 Cypress 指令來模擬使用者在網頁上的互動。

希望這份教學對你有所幫助!如果你有任何進一步的問題,請隨時告訴我。

https://ithelp.ithome.com.tw/upload/images/20231015/20135750ykjHoSH8dM.png

當然,除了前面提到的常用指令,Cypress 還提供了許多其他有用的指令。以下是一些更多常用的 Cypress 指令:

8. cy.clear()

這個指令用於清空輸入框中的文字。

cy.get('#search-input').type('Cypress');
cy.get('#search-input').clear(); // 清空輸入框中的文字

9. cy.check()

這個指令用於勾選(選中)勾選框或選項。

cy.get('#agree-checkbox').check(); // 勾選勾選框

10. cy.uncheck()

這個指令用於取消勾選(取消選中)勾選框或選項。

cy.get('#subscribe-checkbox').uncheck(); // 取消勾選勾選框

11. cy.select(value)

這個指令用於選擇下拉選單中的選項。

cy.get('#country-select').select('Taiwan'); // 選擇下拉選單中的 "Taiwan" 選項

12. cy.scrollTo()

這個指令用於滾動到指定的元素或位置。

cy.get('#footer').scrollTo(); // 滾動到元素
cy.scrollTo('bottom'); // 滾動到頁面底部

13. cy.wait(time)

這個指令用於暫停測試執行,等待一段時間(毫秒)。

cy.wait(2000); // 暫停 2 秒

14. cy.intercept()

這個指令用於攔截和控制網絡請求,以進行模擬和測試。

cy.intercept('GET', '/api/data').as('getData');
cy.visit('https://www.example.com');
cy.wait('@getData'); // 等待攔截的請求完成

這些指令可以幫助你更好地模擬和測試你的應用程式。你可以根據測試的需求選擇適當的指令來完成你的測試案例。

希望這些指令對你有所幫助!如果你有任何進一步的問題或需要更多的指令示例,請隨時告訴我。

到這裡為止,我們學會「選擇」畫面上的元件,也能跟元件做互動了
接下來就要驗證互動結果是不是正確的

Assertions (斷言)

https://ithelp.ithome.com.tw/upload/images/20231015/20135750xY1IoWtfGo.png

當然,我將提供有關 Cypress 中斷言(Assertions)的詳細介紹和完整教學。

Assertions (斷言)

在 Cypress 中,斷言用於檢查特定條件是否成立。如果條件不符合,測試將會失敗。

以下是一些常用的 Cypress 斷言:

1. should()

should() 方法用於斷言一個元素的狀態或行為。

cy.get('.username').should('have.value', 'john_doe'); // 檢查輸入框的值是否為 'john_doe'
cy.get('.error-message').should('contain', '帳號或密碼錯誤'); // 檢查是否包含特定文字
cy.url().should('eq', 'https://www.example.com/dashboard'); // 檢查當前網址是否符合預期

2. expect()

expect() 方法用於進行更複雜的斷言,通常用於檢查函數的回傳值或多個條件。

cy.get('.username').then($element => {
  expect($element.val()).to.equal('john_doe'); // 檢查輸入框的值是否為 'john_doe'
});

完整教學範例

讓我們使用這些斷言來寫一個簡單的 Cypress 測試:

describe('斷言示例', () => {
  it('應該執行正確的斷言', () => {
    cy.visit('https://www.example.com');

    cy.get('#username').type('john_doe');
    cy.get('input[type="password"]').type('password123');

    cy.contains('登入').click();

    cy.url().should('eq', 'https://www.example.com/dashboard');

    cy.get('.welcome-message').should('contain', '歡迎回來,John Doe!');
  });

  it('應該執行其他斷言', () => {
    cy.visit('https://www.example.com');

    cy.get('#username').type('invalid_username');
    cy.get('input[type="password"]').type('invalid_password');

    cy.contains('登入').click();

    cy.get('.error-message').should('contain', '帳號或密碼錯誤');
  });
});

這個範例中包含了兩個測試案例,每個案例都包含了不同的斷言,用於驗證特定的條件。

希望這份教學對你有所幫助!如果你有任何進一步的問題,請隨時告訴我。

OK… 他說有 should()expect() 這兩種方式

針對should() 的用法,再詳細了解一下
https://ithelp.ithome.com.tw/upload/images/20231015/201357506tZ94fLknH.png

當然,讓我提供更詳細的 should() 斷言的教學。

should() 斷言

should() 方法是 Cypress 中用來對選取的元素進行斷言的重要工具。它允許你檢查元素的狀態、值或屬性,以確保應用程式的行為符合預期。

以下是一些常用的 should() 斷言:

1. should('exist')

確認元素是否存在於頁面上。

cy.get('.username').should('exist'); // 確認類別為 "username" 的元素存在

2. should('be.visible')

確認元素是否可見(並不一定要在畫面上可見,但不能被隱藏或擋住)。

cy.get('.login-btn').should('be.visible'); // 確認類別為 "login-btn" 的按鈕可見

3. should('be.hidden')

確認元素是否被隱藏。

cy.get('.hidden-element').should('be.hidden'); // 確認類別為 "hidden-element" 的元素被隱藏

4. should('have.class', 'className')

確認元素是否具有特定的 CSS 類別。

cy.get('.username').should('have.class', 'active'); // 確認類別為 "username" 的元素具有 "active" 類別

5. should('have.value', 'expectedValue')

確認輸入元素的值是否等於預期值。

cy.get('#username').should('have.value', 'john_doe'); // 確認 ID 為 "username" 的輸入元素值為 'john_doe'

6. should('contain', 'expectedText')

確認元素是否包含特定的文字。

cy.get('.welcome-message').should('contain', '歡迎回來,John Doe!'); // 確認包含特定文字

7. should('not.exist')

確認元素不存在於頁面上。

cy.get('.nonexistent-element').should('not.exist'); // 確認類別為 "nonexistent-element" 的元素不存在

8. should('be.disabled')

確認元素是否被禁用。

cy.get('.disabled-btn').should('be.disabled'); // 確認類別為 "disabled-btn" 的按鈕被禁用

這些斷言可以幫助你驗證測試中的不同情境,確保應用程式的行為符合預期。

希望這份更詳細的教學對你有所幫助!如果你有任何進一步的問題,請隨時告訴我。

https://ithelp.ithome.com.tw/upload/images/20231015/20135750EjAbxZr0V3.png

當然,以下是更多常用的 should() 斷言的語法:

9. should('have.attr', 'attributeName', 'expectedValue')

確認元素是否具有特定屬性,並且屬性值等於預期值。

cy.get('a').should('have.attr', 'href', 'https://www.example.com'); // 確認連結的 href 屬性為指定值

10. should('have.css', 'property', 'expectedValue')

確認元素是否具有特定 CSS 屬性,並且屬性值等於預期值。

cy.get('.username').should('have.css', 'color', 'rgb(0, 0, 255)'); // 確認文字顏色為藍色

11. should('have.text', 'expectedText')

確認元素的文字內容是否等於預期文字。

cy.get('.welcome-message').should('have.text', '歡迎回來,John Doe!'); // 確認元素的文字內容

12. should('match', /pattern/)

用正則表達式確認元素的文字內容是否符合特定模式。

cy.get('.username').should('match', /^john/); // 確認文字以 "john" 開頭

13. should('not.have.class', 'className')

確認元素不具有特定的 CSS 類別。

cy.get('.username').should('not.have.class', 'inactive'); // 確認不具有 "inactive" 類別

14. should('have.length', expectedLength)

確認選擇器選取的元素數量等於預期數量。

cy.get('ul li').should('have.length', 5); // 確認有 5 個 li 元素

15. should(callback)

使用自定義函數進行斷言,你可以在函數內部進行更複雜的判斷。

cy.get('.elements').should($elements => {
  // 在這裡進行自定義斷言
  expect($elements).to.have.length(3);
  expect($elements.eq(0)).to.contain('Element 1');
});

這些斷言提供了多種方法來驗證你的應用程式的狀態和行為,並確保它們符合預期。

希望這份更多常用的 should() 斷言對你有所幫助!如果你有任何進一步的問題,請隨時告訴我。

這邊我有一個小小的困惑
上面說確認文字內容的時候
使用了should('have.text', '歡迎回來,John Doe!')

但是在更前面的例子,確認網址文字內容時
使用的是 should('eq', 'https://www.example.com/dashboard')

使用 have.texteq 的差別是什麼呢
請教一下ChatGPT
https://ithelp.ithome.com.tw/upload/images/20231015/20135750UWIn1YAV1v.png

should('have.text', 'expectedText')should('eq', 'expectedText') 之間有些微的差別:

  1. should('have.text', 'expectedText'):
    • 這個斷言會檢查選取的元素的文字內容是否等於預期文字。
    • 它會確認元素的內容是否包含指定的文字。
    • 例如:cy.get('.welcome-message').should('have.text', '歡迎回來,John Doe!') 會確認 .welcome-message 元素的文字內容是否包含 '歡迎回來,John Doe!'
  2. should('eq', 'expectedText'):
    • 這個斷言會比較選取的元素的值(通常是輸入框或特定屬性)是否完全等於預期值。
    • 它用於比較兩個值是否完全相等。
    • 例如:cy.get('#username').should('eq', 'john_doe') 會確認 #username 元素的值是否完全等於 'john_doe'

簡而言之,should('have.text', 'expectedText') 用於檢查元素的文字內容,而 should('eq', 'expectedText') 用於比較值是否完全相等。

舉例來說,如果你想要確認一個表單中的輸入框中的值是否符合預期,你可以使用 should('eq', 'expectedValue') 斷言。然而,如果你想要確認一個段落的文字是否包含特定的文字,你可以使用 should('have.text', 'expectedText') 斷言。

希望這澄清了這兩者之間的差異!如果你有任何進一步的問題,請隨時告訴我。

撰寫原則

https://ithelp.ithome.com.tw/upload/images/20231015/201357501YKSBD1Og4.png

當你開始使用 Cypress 撰寫測試時,以下是一些建議的準則和方式可以幫助你撰寫有效、可維護的測試:

  1. 保持測試簡潔和獨立
    • 每個測試案例應該只測試一個功能或場景,這樣可以使測試更清晰和容易維護。
    • 避免將多個不同的功能或場景放在同一個測試案例中。
  2. 使用描述性的命名
    • 使用清晰的名稱來描述你的測試案例,讓其他人容易理解你的測試在做什麼。
  3. 使用 beforebeforeEach 鉤子
    • 如果你有一些在所有測試之前或每個測試之前都需要執行的設置工作,可以使用這兩個鉤子。
  4. 使用 cy.get() 選擇元素
    • 使用明確且具有描述性的選擇器來選取你要進行操作的元素,避免選取過於通用的選擇器。
  5. 使用 should() 進行斷言
    • 使用 should() 方法來確認應用程式的狀態和行為是否符合預期。
  6. 利用自定義指令和函數
    • 如果你需要在多個測試案例中重複相同的操作,可以考慮將這些操作抽象成自定義指令或函數,以提高代碼的重用性。
  7. 使用 cy.intercept() 攔截請求
    • 在需要模擬網絡請求的情境下,可以使用 cy.intercept() 來攔截並控制請求。
  8. 保持測試環境的穩定性
    • 測試環境應保持穩定,以確保測試結果的可靠性。這可能需要適當的虛擬化或容器化。
  9. 定期重複執行測試
    • 自動執行測試,以確保在代碼變更後不會出現破壞。
  10. 撰寫註解
    • 為了讓其他人或未來的自己能夠理解你的測試,請提供清晰的註解。
  11. 了解 Cypress API
    • 熟悉 Cypress 的 API,以充分利用其功能和特性。
  12. 維護良好的測試套件結構
    • 將測試案例組織成合適的目錄和檔案結構,使其易於尋找和維護。
  13. 定期檢查測試的執行情況
    • 監視測試的執行情況,及時發現和處理可能的問題。

這些建議可以幫助你開始建立健壯、易於維護的 Cypress 測試套件。隨著你的經驗增加,你可能會發現更多的最佳做法和技巧,以使你的測試更加有效。

自定義指令(Custom Commands)和函數(Functions)

https://ithelp.ithome.com.tw/upload/images/20231015/20135750dP1v8QCbFS.png

自定義指令和函數是在 Cypress 測試中你自己寫的程式碼塊,目的是為了將重複的操作或功能封裝成可重用的單元,以提高程式碼的可讀性和維護性。

這兩者之間有一些微妙的區別:

  1. 自定義指令 (Custom Commands)

    • 自定義指令允許你在 Cypress 中創建你自己的指令,這些指令可以像 Cypress 內建的指令一樣使用。
    • 這些指令是全域的,可以在整個測試套件中使用。
    • 通常用於將一組操作封裝成一個可調用的指令,使測試更具可讀性和模組化。

    例如,如果你在多個測試案例中都需要執行相同的一組操作,你可以將這些操作封裝成一個自定義指令,然後在各個測試案例中調用這個指令。

    Cypress.Commands.add('login', (username, password) => {
      cy.get('#username').type(username);
      cy.get('#password').type(password);
      cy.get('.login-btn').click();
    });
    

    然後在測試中可以使用:

    cy.login('john_doe', 'password123');
    
  2. 函數 (Functions)

    • 函數是一段可重複使用的程式碼,可以在任何地方定義和調用,不僅僅是在 Cypress 測試中。
    • 函數可以在需要的時候被調用,可以接受輸入並返回輸出。

    例如,你可以在 Cypress 測試中定義一個函數來執行一組特定的操作:

    function login(username, password) {
      cy.get('#username').type(username);
      cy.get('#password').type(password);
      cy.get('.login-btn').click();
    }
    

    然後在測試中可以使用:

    login('john_doe', 'password123');
    

總的來說,自定義指令和函數都是為了提高程式碼的可讀性、重用性和維護性,並減少重複的程式碼。你可以根據實際需要選擇使用哪一種方法,或者在某些情況下兩者結合使用。

https://ithelp.ithome.com.tw/upload/images/20231015/20135750sKKXQSqMly.png

在 Cypress 中,你可以根據自己的需求和喜好組織自定義指令和函數的檔案結構。以下是一些建議的組織方式:

自定義指令 (Custom Commands)

  1. cypress/support/commands.js 中定義

    • Cypress 預設會將自定義指令放在 cypress/support/commands.js 檔案中。你可以在這個檔案中定義你的自定義指令。

    例如:

    Cypress.Commands.add('login', (username, password) => {
      cy.get('#username').type(username);
      cy.get('#password').type(password);
      cy.get('.login-btn').click();
    });
    
  2. 根據功能拆分自定義指令

    • 如果你的自定義指令變得複雜或包含多個功能,你可以將它們拆分成多個檔案,然後在 commands.js 中引入這些檔案。

    例如:

    // cypress/support/commands.js
    import './loginCommands';
    import './navigationCommands';
    
    // cypress/support/loginCommands.js
    Cypress.Commands.add('login', (username, password) => {
      // 登入相關的指令
    });
    
    // cypress/support/navigationCommands.js
    Cypress.Commands.add('goToHomePage', () => {
      // 前往首頁相關的指令
    });
    

函數 (Functions)

  1. 在單獨的 JavaScript 檔案中定義

    • 將函數定義在單獨的 JavaScript 檔案中,例如 utils.js

    例如:

    // cypress/utils.js
    export function login(username, password) {
      cy.get('#username').type(username);
      cy.get('#password').type(password);
      cy.get('.login-btn').click();
    }
    
  2. 在測試案例中引入函數

    • 在你的測試案例中引入這些函數,然後在需要的時候進行調用。

    例如:

    // cypress/integration/sampleTest.spec.js
    import { login } from '../utils';
    
    describe('Login Test', () => {
      it('should log in successfully', () => {
        login('john_doe', 'password123');
        // 其他斷言和測試步驟
      });
    });
    

總的來說,重要的是保持結構清晰和有組織,讓你和你的團隊能夠輕鬆地理解和維護測試程式碼。選擇最適合你和你的團隊的組織方式是關鍵。

https://ithelp.ithome.com.tw/upload/images/20231015/201357500w4r1PJtmw.png

為了在 E2E 測試中更方便地進行畫面上的元件選擇,你可以考慮以下一些方式:

  1. 使用測試ID (Test IDs)

    • 在元素的屬性中添加一個獨特的測試ID,以便在測試中輕鬆地選擇該元素。

    例如:

    <button data-test="login-btn">登入</button>
    
    cy.get('[data-test="login-btn"]').click(); // 使用測試ID 選取按鈕
    
  2. 使用特定的 CSS 類別 (CSS Classes)

    • 將特定的 CSS 類別添加到元素,以便在測試中更容易地選擇這些元素。

    例如:

    <input class="username-input" />
    
    cy.get('.username-input').type('john_doe'); // 使用 CSS 類別選取輸入框
    
  3. 使用 XPath 或 CSS 選擇器

    • 使用 XPath 或 CSS 選擇器來精確選擇元素,確保選擇器是唯一的。

    例如:

    cy.xpath('//button[contains(text(),"登入")]').click(); // 使用 XPath 選取按鈕
    

    或:

    cy.get('button.login-btn').click(); // 使用 CSS 選擇器選取按鈕
    
  4. 使用 Cypress 命令自定義指令

    • 如果你在多個測試案例中都需要進行相同的操作,可以考慮使用自定義指令來封裝這些操作。

    例如:

    Cypress.Commands.add('selectDropdownOption', (dropdownSelector, optionText) => {
      cy.get(dropdownSelector).click();
      cy.contains(optionText).click();
    });
    

    然後在測試中可以使用:

    cy.selectDropdownOption('#country-dropdown', 'Taiwan'); // 選取下拉選單中的 "Taiwan" 選項
    
  5. 使用測試框架提供的輔助函數

    • 一些測試框架(如 React Testing Library 或 Testing Library)提供了用於在測試中選取元素的輔助函數,可以根據元素的文字或標籤進行選取。

    例如:

    // 使用 React Testing Library
    import { getByText } from '@testing-library/react';
    const button = getByText('登入');
    

以上提供了一些在 E2E 測試中方便選擇畫面元件的方法。根據你的具體情況和偏好,你可以選擇適合你的方法或結合使用多種方法。

統整重點

https://ithelp.ithome.com.tw/upload/images/20231015/20135750lzESWOsM5a.png

在這次的對話中,我們討論了許多與 Cypress 測試相關的重要主題。以下是我們的總結:

  1. Cypress 測試概念
    • Cypress 是一個現代的前端測試工具,具有自動化測試、斷言、模擬網絡等功能。
  2. 基本的 Cypress 指令
    • cy.get() 用於選擇元素。
    • cy.visit() 用於前往網頁。
    • cy.contains() 用於找到包含特定文字的元素。
    • cy.click() 用於模擬點擊事件。
  3. TypeScript 和 Cypress
    • 你可以在 Cypress 測試中使用 TypeScript,並以 .ts 為檔案擴展名。
  4. 自定義指令和函數
    • 自定義指令和函數可以幫助你封裝重複的操作,提高程式碼的可讀性和維護性。
  5. Cypress 中的斷言
    • 使用 should() 方法來斷言元素的狀態、行為或屬性,以確保應用程式的行為符合預期。
  6. Cypress 中的其他常用指令
    • cy.intercept() 用於攔截網絡請求。
    • cy.xpath() 用於使用 XPath 選擇元素。
  7. 建議的檔案結構
    • 自定義指令可以在 cypress/support/commands.js 中定義,也可以根據功能拆分成多個檔案。
    • 函數可以在單獨的 JavaScript 檔案中定義,然後在測試中引入。

總的來說,Cypress 是一個強大的前端測試工具,它可以幫助你建立健壯、可靠的自動化測試。透過熟悉基本指令、斷言和自定義函數的使用,你可以編寫高效且易於維護的測試套件,確保你的應用程式在不斷的開發過程中保持穩定性。

如果你在使用 Cypress 過程中遇到了任何困難,請隨時向我尋求幫助。祝你在前端測試的旅程中順利前行!

結語

Cypress的語法就討論到這邊!
這次的對話記錄在這邊:
https://chat.openai.com/share/26fd0770-f99b-41ba-9977-ec65573663fb

下一篇微微的實際操作&示範用Cypress自動登入IT邦幫忙
我是剛入門e2e測試的前端工程師一宵三筵,我們明天見!


上一篇
【Day32】ChatGPT請教教我:E2E測試!Cypress!(上)- 安裝&設定
下一篇
【Day34】ChatGPT請教教我:E2E測試!Cypress!(下)- 實際演練 & 爬蟲?
系列文
用ChatGPT詠唱來完成工作與點亮前後端技能樹56
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言