Karate 除了 API 測試之外,也支援 UI 測試,讓開發者能以一致的語法進行前後端測試。本文著重於 Chrome 瀏覽器的自動化測試,從設定驅動程式開始,逐步介紹如何開啟網站、尋找元素、與元素互動以及進行斷言。Karate UI 提供了多種元素定位方式,包括 XPath、CSS 選擇器、友善定位器以及萬用字元定位器,方便開發者根據實際情況選擇最合適的定位策略。此外,Karate UI 也支援瀏覽器操作,例如設定視窗大小、導航、重新整理等。文章也示範瞭如何處理網頁元素列表,例如驗證搜尋結果,以及如何使用 waitFor 函式確保網頁元素載入完成後再進行操作,提升測試穩定性。
使用 Karate 編寫基本的 Chrome 測試案例
在接下來的章節中,我們將探討這類別測試的基本功能,以給您一個概覽。這可以作為進一步學習的起點,例如,透過研究完整的 Karate UI 檔案,網址為 https://karatelabs.github.io/karate/karate-core。
相關的測試功能
在本章中,我們將專注於瀏覽器自動化;否則,本文的篇幅將會是現在的兩倍。在繼續之前,我想提一下 Karate 的一些與 UI 測試相關的功能,這些功能值得在此提及:
- Karate UI 可以使用 Appium 專案來測試行動應用程式。但是,這個功能並未得到積極開發,且不被視為同等重要。不過,如果您想了解更多,可以在 https://karatelabs.github.io/karate/examples/mobile-test 找到一些有限的資訊。
- Karate 甚至可以透過特殊的驅動程式與 Playwright 框架進行通訊。這需要設定 Playwright 伺服器,如果您想從 Playwright 轉換到 Karate,這可能是一個值得考慮的選項。更多相關資訊請參閱 https://karatelabs.github.io/karate/karate-core/#playwright。
- Karate 也可以透過建立與 Robot Framework 的橋樑來用於 Windows 桌面應用程式自動化(https://robotframework.org)。您可以透過 https://karatelabs.github.io/karate/karate-robot 瞭解更多關於此整合的資訊。
編寫基本的 Chrome 測試案例
Karate 的檔案建議從自動化 Chrome 瀏覽器開始,因為它是最容易且最具能力的。因此,我們現在將為 Chrome 建立我們的第一個基本瀏覽器測試。
在 Chrome 中開啟網站
我們需要事先知道要使用哪個瀏覽器,以便指定正確的驅動程式。根據此,Karate 將使用所需的瀏覽器和協定。對於本範例,我們將從最簡單的 Chrome 開始。
組態 Karate 驅動程式
我們將建立一個名為「First test」的新場景,並在接下來的章節中逐步新增功能:
Scenario: First test
* configure driver = { type: 'chrome' }
在其他瀏覽器中執行
在本章中,我們將專門使用 Chrome,以避免使瀏覽器測試的介紹變得不必要地複雜。如果您想稍後繼續在不同的瀏覽器中執行 Karate UI 測試,主要只是指定不同的驅動程式型別。可以透過 https://karatelabs.github.io/karate/karate-core/#driver-types 檢視有效的驅動程式型別列表,以及它們用於與網頁瀏覽器通訊的協定。
自定義可執行檔位置
如果您的瀏覽器安裝(或 WebDriver 可執行檔)位於您作業系統上的自定義資料夾中,您可以使用此特殊語法來組態驅動程式:
* configure driver = { type: 'chrome', executable: 'path_to_executable' }
其中,path_to_executable 應包含瀏覽器或 WebDriver 應用程式的完整路徑。如有需要,您也可以在此指定批次檔或 shell 指令碼。不過,這是一種罕見的情況,只有在您需要非常自定義的設定時才需要。
開啟網站
每個瀏覽器測試的第一步是在組態 Karate 驅動程式後開啟特定的網站。當發生這種情況時,Karate 用於與網頁瀏覽器通訊的驅動程式會被初始化,並可用於進一步與頁面上的元素互動、設定 Cookie,以及通常執行使用者在手動導航和使用網頁應用程式時可以執行的所有操作。
開啟網站非常簡單,如下所示:
Given driver 'https://softwaretester.blog'
只需在組態的驅動程式之後指定要開啟的 URL,驅動程式就會連線到瀏覽器並導航到該 URL。請記住,與 Karate API 測試相同的機制適用,這意味著此 URL 也可以從 karate-config.js、輔助功能、系統屬性等取得。
尋找並與元素互動
到目前為止,我們的範例測試只是開啟了一個網站。為了將其變成一個真正的測試,有幾種方法可以定位元素,以便我們可以與它們互動並驗證應用程式或網頁的行為。這是向模擬真實使用者行為在瀏覽器測試中的關鍵一步。
HTML 和 CSS
在處理定位器時,瞭解 HTML 和 CSS 的基礎知識非常有幫助。這些知識使目標元素的定位、理解它們之間的關係以及從中檢索資訊變得更加容易。由於本文主要關於 API 測試,而本章僅對 UI 測試的世界提供有限的洞察,因此值得透過其他來源更仔細地研究這些主題。
瞭解定位器
在 UI 測試的背景下,定位器是用於識別和定位網頁或行動應用程式上的 UI 元素的特性。它們通常用於測試自動化框架中,以與 UI 元素(如按鈕、輸入欄位和下拉式選單)互動。
定位器有不同的型別,取決於用於構建應用程式或網頁的技術。在本文的後續部分,我們將看到您可以在 Karate 中使用的不同定位器。
程式碼解析:
Scenario: First test
* configure driver = { type: 'chrome' }
Given driver 'https://softwaretester.blog'
Scenario: First test定義了一個名為「First test」的測試場景。* configure driver = { type: 'chrome' }組態了 Karate 的驅動程式,使用 Chrome 瀏覽器。Given driver 'https://softwaretester.blog'使用組態好的驅動程式開啟了指定的 URL。
此圖示說明瞭 Karate UI 測試的基本流程:
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Karate UI 測試入門
package "軟體測試架構" {
package "測試層級" {
component [單元測試
Unit Test] as unit
component [整合測試
Integration Test] as integration
component [端對端測試
E2E Test] as e2e
}
package "測試類型" {
component [功能測試] as functional
component [效能測試] as performance
component [安全測試] as security
}
package "工具框架" {
component [pytest] as pytest
component [unittest] as unittest
component [Selenium] as selenium
component [JMeter] as jmeter
}
}
unit --> pytest : 撰寫測試
unit --> integration : 組合模組
integration --> e2e : 完整流程
functional --> selenium : UI 自動化
performance --> jmeter : 負載測試
note right of unit
測試金字塔基礎
快速回饋
高覆蓋率
end note
@enduml此圖示呈現了使用 Karate UI 進行測試的基本步驟,從組態驅動程式到驗證結果。
Karate UI 自動化測試中的元素定位技術
在進行 UI 自動化測試時,元素定位是至關重要的一環。Karate 支援多種元素定位方式,包括 XPath、CSS 選擇器、友善定位器(Friendly Locators)以及萬用字元定位器(Wildcard Locators)。瞭解這些定位方式的優缺點有助於我們撰寫更穩定、更易於維護的測試指令碼。
使用 XPath 進行元素定位
XPath 是一種用於在 XML 檔案中定位元素的語言,由於 HTML 可以視為一種特殊的 XML,因此 XPath 也可用於網頁元素的定位。以下是一些常用的 XPath 語法:
//:選取檔案中的任意元素,可根據標籤名稱、屬性值或與其他元素的關聯進行定位。[@attribute]:選取具有特定屬性的元素,例如//*[@id]會選取所有具有id屬性的元素。[@attribute='value']:選取具有特定屬性值的元素,例如//*[@class='btn']會選取所有class屬性為btn的元素。//tag[text()='text']:選取具有特定文字內容的元素,例如//h1[text()='Welcome']會選取文字內容為Welcome的h1元素。parent:::選取目前元素的父元素。following-sibling::和preceding-sibling:::選取目前元素之後或之前的兄弟元素。
XPath 程式碼範例
//*[@id='submit-button']
內容解密:
上述 XPath 表示式用於選取 id 為 submit-button 的元素。其中,//* 表示選取檔案中的任意元素,[@id='submit-button'] 表示篩選出 id 屬性為 submit-button 的元素。
使用 CSS 選擇器進行元素定位
CSS 選擇器是一種更簡潔的元素定位方式,可以根據元素的標籤名稱、ID、類別或其他屬性進行選取。以下是一些範例:
tagname:根據標籤名稱選取元素,例如button會選取所有的button元素。.classname:根據類別名稱選取元素,例如.btn會選取所有類別為btn的元素。#id:根據 ID 屬性選取元素,例如#submit-button會選取id為submit-button的元素。:nth-child(n):選取父元素下的第 n 個子元素。:not(selector):選取不符合指定選擇器的元素。
CSS 選擇器程式碼範例
button.btn
內容解密:
上述 CSS 選擇器用於選取所有類別為 btn 的 button 元素。其中,button 表示選取 button 元素,.btn 表示篩選出類別為 btn 的元素。
使用友善定位器(Friendly Locators)
友善定位器是一種根據元素相對位置的定位方式,可以提高測試指令碼的穩定性和可讀性。以下是一些範例:
rightOf('label'):選取位於指定標籤右側的元素。leftOf('label'):選取位於指定標籤左側的元素。above('.content'):選取位於指定元素上方的元素。below('.header'):選取位於指定元素下方的元素。near('h1'):選取位於指定元素附近的元素。
友善定位器程式碼範例
rightOf('label').find('input')
內容解密:
上述友善定位器用於選取位於 label 元素右側的 input 元素。其中,rightOf('label') 表示選取位於 label 右側的元素,.find('input') 表示進一步篩選出 input 元素。
使用萬用字元定位器(Wildcard Locators)
萬用字元定位器可以使用文字和萬用字元來識別網頁上的元素。以下是一些範例:
{}text``:根據精確的文字內容進行定位。- `{’^’}text``:根據部分文字內容進行定位。
- `{’tag:2’}text``:根據標籤名稱和位置進行定位。
萬用字元定位器程式碼範例
{'h1'}Hello
內容解密:
上述萬用字元定位器用於選取文字內容為 Hello 的第一個 h1 元素。其中,{'h1'} 表示根據標籤名稱進行篩選,Hello 表示精確的文字內容。
綜上所述,Karate 提供了多種元素定位方式,可以根據具體需求選擇合適的定位方式,以提高測試指令碼的穩定性和可維護性。
使用 Karate UI 進行瀏覽器測試:尋找與操作元素
在進行瀏覽器測試時,尋找和操作網頁元素是至關重要的一步。Karate 提供了一系列強大的方法來實作這一點。
決定元素定位器
要找到目標元素的定位器(locator),最簡單的方法是使用 Chrome 瀏覽器內的 Chrome DevTools。可以透過按下 F12 或點選右上角的三個點並選擇「更多工具」中的「開發者工具」來開啟 DevTools。
圖 9.1 – DevTools 元素選擇
點選元素選擇按鈕(顯示為帶有滑鼠指標的正方形)可以讓我們定位到特定的元素。Elements 標籤頁中顯示了整個頁面的原始碼,並突出了所選元素的 HTML 程式碼。
或者,也可以透過右鍵單擊網頁元素並選擇「檢查」來啟用此檢視。
圖 9.2 – 使用檢查選單
圖 9.3 – 在 Chrome DevTools 中探索元素
當我們將滑鼠懸停在搜尋輸入框上時,它會被突出顯示,並顯示一個工具提示,提供了有關其 CSS 類別、顏色和大小的資訊。同時,右側的 HTML 程式碼也會突出顯示該輸入元素。
選擇合適的定位器
根據這些資訊,我們可以選擇一個合適的定位器來在 Karate 測試中使用。一個好的定位器應該具備以下特性:
- 唯一性:定位器應該能夠識別頁面上的單一元素,而不是多個元素。
- 穩定性:定位器應該穩定且強壯,不應該頻繁更改,以免導致測試失敗。
- 可讀性:定位器應該易於閱讀和理解,以便於維護和更新。
- 一致性:定位器應該在不同的瀏覽器和平台上保持一致,以便於跨瀏覽器和裝置的測試。
- 可維護性:定位器應該易於維護和更新,以適應網頁應用程式的演變。
讓我們再次檢視所選輸入欄位的原始碼:
<input name="searchfield" class="search-input" aria-label="search" type="text" data-min="3" required="" placeholder="Search ..." value="" data-search-invalid="Please add at least 3 characters" data-search-separator=":" data-search-input="/search/query">
突出顯示的程式碼部分顯示了我們可以用作定位器的良好特性。例如,我們可以看到這是唯一具有 search-input CSS 類別的元素。
與元素互動
Karate 提供了一系列特定的方法來與元素互動,包括:
click(locator):點選匹配給定定位器的元素input(locator, value):設定匹配給定定位器的輸入元素的值select(locator, value):從匹配給定定位器的下拉元素中選擇具有給定值的選項scroll(locator):滾動到匹配給定定位器的元素back():導航回前一頁forward():導航到下一頁refresh():重新整理當前頁面close():關閉當前瀏覽器視窗
在測試場景中使用互動
現在,我們可以將從 DevTools 取得的資訊組合起來,建立第一個場景:
Scenario: 第一個測試
* configure driver = { type: 'chrome' }
Given driver 'https://softwaretester.blog'
When input('.search-input', ['Magic', Key.ENTER])
And waitForUrl('search/query:Magic')
在這裡,我們增加了兩個步驟:
- 使用
.search-input定位器定位搜尋輸入框,並使用 Karate 的input方法填寫Magic搜尋詞。注意,我們使用了一個特殊的語法,先寫入Magic字串,然後按下 Enter 鍵(由Key.ENTER指定)。 - 使用
waitForUrl方法等待 URL 包含指定的字串search/query:Magic。
如果我們現在執行此測試,它應該會透過,並生成以下 Karate 測試報告:
圖 9.4 – 成功 UI 測試
Chrome 錯誤
對於某些 Chrome 版本(例如 111),可能會出現以下錯誤:
com.intuit.karate - driver config / start failed: io.netty.handler.codec.http.websocketx.WebSocketClientHandshakeException: Invalid handshake response getStatus: 403 Forbidden, options: {type=chrome, target=null}
程式碼解密:
input('.search-input', ['Magic', Key.ENTER])這行程式碼的作用是對.search-input的元素輸入Magic並按下Enter鍵。其中,Key.ENTER代表Enter鍵。waitForUrl('search/query:Magic')這行程式碼的作用是等待當前URL包含search/query:Magic。.search-input是用來識別搜尋框的元素定位符。- 使用陣列形式的輸入,可以在輸入框內先輸入文字,再按下特定按鍵。
- 當搜尋完成後,URL會變成包含特定字串,藉由檢查此字串驗證搜尋是否成功。
- 這種方式確保測試能正確執行,並檢查相關功能是否正常運作。
Karate UI 測試:尋找與互動網頁元素
開始使用 Karate UI 進行瀏覽器測試
在進行瀏覽器測試時,Karate UI 提供了一個強大且靈活的工具來與網頁元素互動。以下是一個範例,展示如何使用 Karate UI 組態瀏覽器並開啟一個網站。
設定瀏覽器並開啟網站
Scenario: 檢查產品名稱
* configure driver = { type: 'chrome' }
Given driver 'https://www.demoblaze.com'
And driver.dimensions = {x: 0, y: 0, width: 1024, height: 768}
程式碼解密:
configure driver = { type: 'chrome' }:設定瀏覽器驅動程式為 Chrome。Given driver 'https://www.demoblaze.com':開啟指定的網站。And driver.dimensions = {x: 0, y: 0, width: 1024, height: 768}:設定瀏覽器視窗的大小和位置。
對網頁元素進行斷言
在瀏覽器測試中,除了與元素互動外,還需要等待某些條件並匹配資料。以下範例展示如何導航到特定類別並驗證第一個產品的名稱。
導航到 Monitors 類別並驗證產品名稱
And waitForEnabled('{a}Monitors').click()
* waitForUrl('/#')
* def productName = text('.card-title')
* match productName == 'Apple monitor 24'
程式碼解密:
waitForEnabled('{a}Monitors').click():等待 Monitors 連結可點選並執行點選動作。waitForUrl('/#'):等待 URL 包含/#,通常用於等待頁面跳轉完成。def productName = text('.card-title'):取得第一個具有card-title類別的元素文字,並儲存在productName變數中。match productName == 'Apple monitor 24':斷言productName是否等於預期的字串。
處理網頁元素列表
以下範例展示如何使用 Karate UI 處理網頁元素列表,並驗證搜尋結果。
搜尋並驗證結果列表
Scenario: 使用元素列表
* configure driver = { type: 'chrome' }
Given driver 'https://computer-database.gatling.io/'
* driver.maximize()
* def searchTerm = 'MacBook'
When input('#searchbox', searchTerm)
And click('#searchsubmit')
* def resultRows = locateAll('table.computers tbody tr')
* assert karate.sizeOf(resultRows) > 0
* def computers = []
* def getNames = function(row) { karate.appendTo(computers, row.children[0].text) }
* karate.forEach(resultRows, getNames)
* match each computers contains searchTerm
程式碼解密:
input('#searchbox', searchTerm):在搜尋框中輸入searchTerm的值。click('#searchsubmit'):點選搜尋按鈕。locateAll('table.computers tbody tr'):定位所有符合 CSS 選擇器的元素,並傳回一個列表。karate.sizeOf(resultRows) > 0:檢查結果列表是否非空。karate.forEach(resultRows, getNames):遍歷結果列表,並對每個元素執行getNames函式。match each computers contains searchTerm:斷言每個電腦名稱是否包含searchTerm。