簡介
先前在我們的網頁測試系列中

我們學習了如何使用 Nightwatch 設定測試環境,並成功編寫了我們的第一個端對端測試。以下是快速回顧:
安裝: npm init nightwatch
編寫: browser.navigateTo('/').assert.textEquals('h1', '<TEXT>')
執行: npx nightwatch test
本文概述
僅檢查文字不足以作為端對端測試,來確保網站和網頁應用程式的可靠性。網頁由複雜的元素組成,並且涉及大量的使用者互動。在本教學中,我們將教您如何從我們編寫的第一個測試繼續,來測試一些常見的場景。
編寫網頁測試主要圍繞這 3 個組成部分:
- 尋找元素
- 與元素互動
- 測試元素及其屬性
我們將涵蓋測試的這三個主要方面,以便能夠為以下場景編寫測試。
- 點擊「Get Started」按鈕,並驗證是否已進入安裝頁面。
- 點擊搜尋,輸入查詢「frame」,等待結果,按下向下箭頭到第二個結果,然後按下 Enter。驗證是否已進入
.parentFrame()
文件頁面。
您也可以觀看本文的影片教學。
尋找 👀
網頁測試的第一步是尋找我們要測試的頁面中的 DOM 元素。Nightwatch 允許您使用各種選擇器來尋找元素。最常見的方法是使用 CSS 選擇器。您可以使用 .element.find()
API 來執行此操作。
除此之外,您還可以通過下面顯示的各種其他方法在頁面上搜尋元素。在以下範例中,我們將使用 .find()
、.findByText()
和 .findByPlaceholderText()
。您可以在此處瞭解更多有關所有可用的選擇器。

您也可以通過鏈接所有尋找 API 來深入搜尋元素。這真的讓您更容易取得您想要的確切元素。
範例
browser.element.find('main').find('.hero').findByText('Get Started')
等待
有時我們要尋找的元素尚未準備好,我們可能需要等待它。一個很好的例子是在輸入框中輸入內容並等待結果填充。您可以使用 .waitUntil(<status>)
API 來執行此操作。
.find(<string>)
- 字串應該是有效的 CSS 選擇器.findByText(<string>)
.findByPlaceholderText(<string>)
.waitUntil(<string>)
- <string>
可以是以下任何一個:"visible"
、"not.visible"
、"selected"
、"not.selected"
、"enabled"
、"not.enabled"
或 "disabled"
範例
// Find the element with class "DocSearch-Modal" and wait for it to be visible
browser.element.find('.DocSearch-Modal').waitUntil('visible')
現在我們已經學習如何尋找元素,我們可以繼續與之互動。
互動 ✍️
下一步是與網頁互動。最常見的場景是使用者點擊按鈕或填寫表單。當測試動態網頁應用程式或網站時,測試的這一部分變得至關重要。
Nightwatch 可透過元素互動 API browser.element.find().<interaction_api>()
來協助您模擬這些動作。這些是可用的互動 API:clear、click、dragAndDrop、sendKeys、setAttribute、setProperty、submit、update、upload、submitForm、updateValue、uploadFile、clickAndHold、doubleClick、rightClick 和 moveTo。
除此之外,您還可以使用 .perform()
執行複雜的使用者操作。但在本部落格的範圍內,我們只會使用 .click()
和 .sendKeys()
。
.click()
- 點擊我們找到的元素.sendKeys(<string | [...keycodes]>)
- 要傳送到所選元素的鍵盤輸入→ arg:
<string>
要作為鍵盤輸入發送的文字。例如,.sendKeys("hello world!")
→ arg:
<[...keycodes]>
您也可以傳送字串和鍵盤代碼的列表,包括在 browser.keys.<special_key>
下找到的特殊按鍵。例如,.sendKeys([browser.Keys.TAB, "hello", browser.Keys.ENTER])
。您可以在此處找到特殊按鍵的清單。範例
// Find the button "Get Started" and click it
browser.element.findByText('Get Started').click()
// Find the input box with placeholder "Search docs" and type "frame"
browser.element.findByPlaceholderText('Search docs').sendKeys('frame')
// Press the down arrow and press Enter
browser.element.findByPlaceholderText('Search docs').sendKeys([browser.Keys.ARROW_DOWN, browser.Keys.ENTER])
現在我們已經學習如何與元素互動,我們可以繼續驗證元素的各個方面。
斷言 ✅
最後一步是測試我們要尋找的內容是否與網頁上顯示的內容相符。這涉及獲取我們需要的元素的屬性並驗證它。
尋找屬性
元素最常測試的方面是其文字、屬性(包括類別)和值(對於輸入元素)。這可以使用 .getText()
、.getAttribute()
和 .getValue()
來實現。您可以在此處閱讀更多關於所有元素狀態的資訊。
測試
一旦我們找到我們需要的值,下一步就是測試它。測試可以根據以下三種方法,以您喜歡的寬鬆或嚴格方式編寫:equals
、contains
和 matches
。
.assert.equals(<str>)
- 接受一個字串並檢查它是否完全相同。.assert.contains(<str>)
- 接受一個字串並檢查輸入是否存在為子字串。.assert.matches(<regex>)
- 接受一個 regex 作為輸入並針對它進行驗證。範例
// Check if the h1 text contains "Install Nightwatch"
browser.element.find('h1').getText().assert.contains('Install Nightwatch')
// Check if the "autocomplete" attribute of the input box is exactly "off"
browser.element.findByPlaceholderText('Filter by title').getAttribute('autocomplete').assert.equals('off')
.verify
而不是 .assert
來記錄失敗並繼續測試中的其他斷言。否定
若要檢查某個事物是否「不」相等或「不」包含,只需在 .assert
後面加入 .not
即可。
// Check if the h1 does not text contains "Selenium"
browser.element.find('h1').getText().assert.not.contains('Selenium')
元素狀態
您可以在 .assert
之後使用 .visible()
、.present()
、.selected()
和 .enabled()
來斷言元素的狀態。這與我們在等待部分先前學習的 .waitUntil
狀態非常相似,並且可以互換使用。
// Check if the element with class "DocSearch-Dropdown-Container" is present
browser.element.find('.DocSearch-Dropdown-Container').assert.present()
文件狀態
您可以使用 browser.assert.url[Contains/Matches/Equals](<string>)
和 browser.assert.title[Contains/Matches/Equals](<string>)
來斷言文件的標題和 URL。
// Check if the title contains "Getting Started"
browser.assert.titleContains('Getting Started')
將所有內容整合在一起 🧩
使用我們到目前為止學到的所有內容,讓我們為這兩種情境編寫測試。
情境:點擊「Get Started」應導向安裝頁面
程式碼
it('Should lead to the installation page on click of Get Started', function (browser) {
browser.navigateTo('/')
browser.element.findByText('Get Started').click()
browser.element.findByPlaceholderText('Filter by title').waitUntil('visible')
browser.element.find('h1').getText().assert.equals('Install Nightwatch')
browser.assert.titleEquals('Getting Started | Developer Guide | Nightwatch.js')
browser.assert.urlContains('nightwatchjs.org/guide/quickstarts')
browser.element.findByPlaceholderText('Filter by title')
.getAttribute('autocomplete').assert.equals('off')
;
browser.end()
})
說明
首先,我們使用 .navigateTo('/')
導航到首頁。這是可能的,因為先前在我們專案的設定中,我們將專案的 base_url
設定為 Nightwatch 首頁。您可以在 nightwatch.conf.js
檔案中編輯此設定。導航完成後,我們找到文字為「Get Started」的按鈕並點擊它。對於在前端路由且不會重新載入頁面的連結,建議等待動作完成。在這裡,我們將等待左側搜尋欄變成可見。然後,我們將透過斷言標題、URL 和 h1
元素來檢查安裝頁面。我們也將斷言搜尋欄的「autocomplete」屬性,以展示屬性斷言。
browser.end()
會關閉瀏覽器視窗。最好以關閉瀏覽器來結束測試。情境:應允許搜尋並顯示正確的結果
程式碼
it('Should allow search and show correct results', function (browser) {
browser.navigateTo('/')
browser.element.find('#docsearch').click()
browser.element.find('.DocSearch-Modal').waitUntil('visible')
const search_input = browser.element.findByPlaceholderText('Search docs')
search_input.sendKeys('frame')
browser.element.find('.DocSearch-Dropdown-Container').assert.present()
search_input.sendKeys([browser.Keys.ARROW_DOWN, browser.Keys.ENTER])
browser.element.find('h1').getText().assert.contains('.frameParent')
browser.end()
})
說明
我們將導航到首頁,找到搜尋圖示並點擊它。我們將等待模態視窗開啟並可見。然後,我們將在搜尋輸入欄中輸入文字「frame」。我們透過檢查 ".DocSearch-Dropdown-Container"
的存在來等待結果載入,一旦結果載入,我們將按下向下箭頭並輸入。這將導向第二個結果 .frameParent()
的文件,並且我們驗證 h1
文字以確認這一點。
最終檔案
最終的 home.spec.js
應該如下所示。
describe('Nighwatch homepage', function () {
it('Should have the correct title', function(browser) {
browser
.navigateTo('/')
.assert.textEquals('h1', 'Introducing Nightwatch v3')
.end()
;
})
it('Should lead to the installation page on click of Get Started', function (browser) {
browser.navigateTo('/')
browser.element.findByText('Get Started').click()
browser.element.findByPlaceholderText('Filter by title').waitUntil('visible')
browser.element.find('h1').getText().assert.equals('Install Nightwatch')
browser.assert.titleEquals('Getting Started | Developer Guide | Nightwatch.js')
browser.assert.urlContains('nightwatchjs.org/guide/quickstarts')
browser.element.findByPlaceholderText('Filter by title')
.getAttribute('autocomplete').assert.equals('off')
;
browser.end()
})
it('Should allow search and show correct results', function (browser) {
browser.navigateTo('/')
browser.element.find('#docsearch').click()
browser.element.find('.DocSearch-Modal').waitUntil('visible')
const search_input = browser.element.findByPlaceholderText('Search docs')
search_input.sendKeys('frame')
browser.element.find('.DocSearch-Dropdown-Container').assert.present()
search_input.sendKeys([browser.Keys.ARROW_DOWN, browser.Keys.ENTER])
browser.element.find('h1').getText().assert.contains('.frameParent')
browser.end()
})
})
讓我們使用我們在上一篇文章中學習的相同命令來執行測試。
npx nightwatch test
瀏覽器完成測試後,輸出應該如下所示。

接下來
網頁測試中的進階技術和情境
今天您學習如何使用這三種技術 → 尋找、互動和斷言來測試網路上的常見使用案例。在我們的網頁測試系列下一章中,我們將學習網頁測試中的進階技術,例如測試掛鉤、多標籤互動、iFrame、複製/貼上、使用 async/await、執行用戶端 JS、模擬地理位置、處理影子 DOM、動作 API 等等。請繼續關注我們即將推出的關於網頁測試中進階技術和情境的文章。
加入我們的社群 💬
如果您有任何問題,請隨時造訪我們的 Discord 伺服器 並打個招呼。我們的社群隨時提供支援、分享見解,並協助您處理任何與測試相關的諮詢。我們歡迎您積極參與,並期待在我們的 Discord 社群中與您聯繫。您也可以透過 Twitter 與我們聯繫。
測試愉快!🎉
影片教學
