這篇文章解釋了如何開始使用xk6-browser,這是一個k6 擴充,它添加了浏覽器級 API 以與浏覽器互動并收集網絡性能名額作為 k6 測試的一部分。
超越協定級别的測試
多年來,k6 已成為衆所周知的性能測試工具,可提供最佳的開發人員體驗。我們的大部分工作都集中在提供一種工具來幫助測試您的伺服器或後端系統。我們全面的負載測試指南建議将使用者牢記在心,後端性能測試隻解決了性能測試工作的一半。
假設您測試網站的使用者體驗并驗證在特定使用者旅程中沒有性能問題。在這種情況下,您需要從浏覽器的角度推動一些性能測試工作,并考慮對使用者流進行更現實的端到端測試。
大多數負載測試工具專注于測試 API 端點,但這與您的使用者通常與之互動的不同。您的使用者與浏覽器進行互動,是以測試浏覽器的性能以擷取端到端的視角來了解與您的 Web 應用程式互動時發生的情況也很重要。
前端和後端性能測試在單獨進行時各有利弊,我們在下面的視訊中對此進行了更詳細的讨論。
在 k6,我們希望開始擴充我們的性能測試用例,并在協定級别之外進行測試。
這就是 xk6-browser 的用武之地。
什麼是xk6浏覽器?
xk6-browser 為 k6 帶來浏覽器自動化和端到端 web 測試,同時支援核心 k6 功能。它使您能夠在性能測試期間從前端應用程式中獲得見解。
您可以使用 xk6-browser 在單個統一腳本中混合浏覽器級别和協定級别的測試。這可以模拟來自協定級測試的大部分流量,并在浏覽器級别運作一個或兩個虛拟使用者來模拟使用者與您的網站互動的方式,進而利用混合方法進行性能測試。
xk6-browser 提供了一個獨特的解決方案,因為您不必使用單獨的工具來測試您的前端和後端系統。xk6-browser 還提供簡化的體驗和性能名額的聚合視圖。
開始使用 xk6-browser
要開始,您需要做的第一件事是安裝 xk6-browser。目前,它正在開發為 k6 擴充。但是,我們計劃很快将其添加為 k6 核心中的實驗子產品。
編寫測試
安裝 xk6-browser 後,您可以複制我們的示例腳本之一作為xk6-browser 文檔的一部分開始使用。
腳本.js
import { chromium } from 'k6/x/browser';
export default function () {
const browser = chromium.launch({ headless: false });
const page = browser.newPage();
}
讓我們分析一下前面的代碼發生了什麼。
- 我們正在進口鉻來自k6/x/浏覽器子產品。鉻是類型浏覽器類型,這是 xk6-browser 啟動浏覽器程序的入口點。
- 接下來,我們使用場景函數,一個現有的 k6 功能,來定義我們的 VU(虛拟使用者)代碼。
- 要建立一個新的浏覽器執行個體,我們使用發射的方法鉻,傳回一個浏覽器目的。您可以在其中傳遞不同的參數發射您可以傳遞的參數之一是無頭,您可以使用它來顯示浏覽器或不顯示。
- 要在您的浏覽器執行個體中建立一個新頁面,我們使用浏覽器.newPage().
現在,進入有趣的部分!讓我們模拟一個使用者通路測試應用程式并登入。
腳本.js
import { chromium } from 'k6/x/browser';
import { check } from 'k6'
export default function () {
const browser = chromium.launch({ headless: false });
const page = browser.newPage();
page
.goto('https://test.k6.io/my_messages.php', { waitUntil: 'networkidle' })
.then(() => {
// Enter login credentials and login
page.locator('input[name="login"]').type('admin');
page.locator('input[name="password"]').type('123');
// Wait for asynchronous operations to complete
return Promise.all([
page.waitForNavigation(),
page.locator('input[type="submit"]').click(),
]).then(() => {
check(page, {
'header': page.locator('h2').textContent() == 'Welcome, admin!',
});
});
}).finally(() => {
page.close();
browser.close();
});
}
前面的代碼中發生了很多事情,特别是異步操作的引入,我們再分解一下。
- 我們通過使用通路頁面頁面.goto并傳遞測試應用程式 URL。我們也在等待網絡空閑,如果至少 500 毫秒沒有網絡連接配接,這将成功。頁面.goto也是一個異步操作,是以這會傳回一個承諾。
- 一旦承諾得到解決,我們使用頁面定位器與我們想要的元素進行互動。在示例中,我們正在建立兩個定位器。一個用于登入名,另一個用于登入密碼。我們使用類型方法在字段中鍵入名稱和密碼。
- 要單擊登入按鈕,我們使用點選方法,這是一個異步操作。單擊送出按鈕也會導緻我們需要等待加載的頁面導航,是以page.waitForNavigation(),另一個異步操作,是必需的,因為在導航完成之前頁面不會準備就緒。
- 由于有兩個異步操作,我們需要使用承諾.all([])在繼續避免任何競争條件之前等待兩個承諾得到解決。
- 接下來,我們使用 k6 中的檢查功能來斷言特定元素的文本内容。
- 最後,我們關閉頁面和浏覽器。
運作測試
要運作測試,請打開您選擇的終端,導航到安裝 xk6-browser 二進制檔案的目錄,然後使用以下指令。
xk6-browser run script.js
複制
如果您在運作該指令時遇到任何問題,請檢視我們的運作測試文檔。
随着浏覽器的啟動,這會為您的使用者實際看到的内容提供更直覺的體驗,是以您還可以找到盲點并發現與浏覽器相關的問題,這些問題在協定級别上無法檢測到。
浏覽器名額
當它完成運作時,除了 k6 已經跟蹤的名額之外,其他浏覽器名額作為 k6 摘要輸出的一部分被跟蹤。
browser_dom_content_loaded.......: avg=36.72ms min=544µs med=22.61ms max=87.02ms p(90)=74.14ms p(95)=80.58ms
browser_first_contentful_paint...: avg=47.52ms min=22.01ms med=47.52ms max=73.02ms p(90)=67.92ms p(95)=70.47ms
browser_first_meaningful_paint...: avg=75.22ms min=75.22ms med=75.22ms max=75.22ms p(90)=75.22ms p(95)=75.22ms
browser_first_paint..............: avg=45.72ms min=21.96ms med=45.72ms max=69.49ms p(90)=64.73ms p(95)=67.11ms
browser_loaded...................: avg=38.14ms min=5.28ms med=22.45ms max=86.68ms p(90)=73.83ms p(95)=80.26ms
筆記
上述名額仍可能發生變化。我們的目标是能夠報告核心 Web Vitals以及其他 Web Vitals,以便更好地了解使用者體驗。
xk6-浏覽器API
xk6 -browser API旨在為 NodeJS 提供與Playwright API的粗略相容性,這意味着 k6 使用者不必學習全新的 API。
目前,k6 API 是同步的。但是,由于許多浏覽器操作是異步發生的,并且為了更緊密地遵循 Playwright API,我們正在努力将大多數 xk6-browser 方法遷移為異步的。這意味着雖然 xk6-browser 已準備好使用,但請注意我們的 API 仍在進行一些更改。
目前,很少有方法,例如頁面.goto(),page.waitForNavigation()和定位器.click()傳回JavaScript 承諾。将來,為了簡單起見,我們将能夠支援 async 和 await 文法。
有關如何使用 xk6-browser API 的更多示例,請檢視xk6-browser 示例。
性能測試的混合方法
如果您隻考慮 Web 性能,當應用程式的流量增加時,這可能會導緻對整體應用程式性能的錯誤信心。
仍然強烈建議同時測試您的後端系統,以通過協定級别全面了解您的應用程式的性能。
但是,存在與通過協定級别進行測試相關的問題,例如:
- 不接近使用者體驗,因為它跳過了浏覽器,
- 随着應用程式的增長,腳本建立起來可能很長并且難以維護,
- 浏覽器性能名額被忽略。
另一方面,如果您通過啟動大量浏覽器來執行負載測試,這将需要更多的負載生成資源,這最終可能會非常昂貴。
為了解決每種方法的缺點,推薦的做法是采用混合方法進行性能測試,這是通過協定和浏覽器級别測試後端和前端系統的組合。使用混合方法,您可以通過協定級别啟動大部分負載,然後同時擁有一個或兩個浏覽器級别的虛拟使用者,是以您還可以檢視前端發生的情況。
性能測試的混合方法
xk6-browser 的偉大之處在于它可以為您提供這種混合的性能測試方法。雖然您可以使用多種工具來執行此操作,但使用 xk6-browser 的好處在于它建構在 k6 之上,這意味着您可以在同一腳本中進行協定級别和浏覽器級别的測試。
讓我們看看它是如何轉化為代碼的。
編寫測試
我們推薦的一個常見場景是将較小的浏覽器級測試子集與較大的協定級測試混合。要同時運作浏覽器級别和協定級别的測試,您可以使用場景。
腳本.js
import { chromium } from 'k6/x/browser';
import { check } from 'k6';
import http from 'k6/http';
export const options = {
scenarios: {
browser: {
executor: 'constant-vus',
exec: 'browser',
vus: 1,
duration: '10s',
},
news: {
executor: 'constant-vus',
exec: 'news',
vus: 20,
duration: '1m',
},
},
};
export function browser() {
const browser = chromium.launch({ headless: false });
const page = browser.newPage();
page
.goto('https://test.k6.io/browser.php', { waitUntil: 'networkidle' })
.then(() => {
page.locator('#checkbox1').check();
check(page, {
'checkbox is checked': (p) =>
p.locator('#checkbox-info-display').textContent() === 'Thanks for checking the box',
});
})
.finally(() => {
page.close();
browser.close();
});
}
export function news() {
const res = http.get('https://test.k6.io/news.php');
check(res, {
'status is 200': (r) => r.status === 200,
});
}
複制
讓我們再次分解前面的代碼。
- 我們正在使用選項來配置我們的測試運作行為。在這個特定的腳本中,我們聲明了兩種場景來配置特定的工作負載,一種用于浏覽器級别的測試,稱為浏覽器一個用于協定級測試,稱為消息.
- 這倆浏覽器和消息場景正在使用constant-vu 執行器,它引入了恒定數量的虛拟使用者,以在指定的時間内執行盡可能多的疊代。
- 接下來,聲明了兩個 JavaScript 函數,浏覽器()和消息(). 這些函數包含将由虛拟使用者執行的代碼。這浏覽器()函數,代表我們的浏覽器級測試,隻需通路一個測試 URL,單擊一個複選框并驗證該複選框是否已成功勾選,同時消息()函數,代表我們的協定級測試,向不同的 URL 發送 GET 請求并檢查狀态代碼是否傳回 200。
- 由于我們使用的是場景,這兩個功能是互相獨立的,是以是并行運作的。
運作測試
使用與上面相同的 xk6-browser 運作指令,您應該會看到類似如下的測試輸出:
running (1m00.1s), 00/21 VUs, 12953 complete and 0 interrupted iterations
browser ✓ [======================================] 1 VUs 10s
news ✓ [======================================] 20 VUs 1m0s
✓ status is 200
✓ checkbox is checked
browser_dom_content_loaded.......: avg=12.27ms min=68µs med=11.76ms max=26.77ms p(90)=25.56ms p(95)=26.36ms
browser_first_contentful_paint...: avg=21.93ms min=12.5ms med=25.32ms max=26.19ms p(90)=25.83ms p(95)=26.01ms
browser_first_paint..............: avg=21.88ms min=12.45ms med=25.27ms max=26.14ms p(90)=25.78ms p(95)=25.96ms
browser_loaded...................: avg=12.18ms min=984µs med=11.74ms max=25.65ms p(90)=24.37ms p(95)=25.19ms
checks...........................: 100.00% ✓ 12953 ✗ 0
data_received....................: 21 MB 341 kB/s
data_sent........................: 1.4 MB 24 kB/s
http_req_blocked.................: avg=2.14ms min=1µs med=2µs max=290.37ms p(90)=4µs p(95)=4µs
http_req_connecting..............: avg=1.09ms min=0s med=0s max=195ms p(90)=0s p(95)=0s
http_req_duration................: avg=90.59ms min=80.93ms med=92.8ms max=542.92ms p(90)=96.89ms p(95)=102.83ms
{ expected_response:true }.....: avg=90.49ms min=80.93ms med=92.8ms max=542.92ms p(90)=96.86ms p(95)=102.81ms
http_req_failed..................: 0.00% ✓ 0 ✗ 12946
http_req_receiving...............: avg=154.41µs min=17µs med=47µs max=97ms p(90)=67µs p(95)=76µs
http_req_sending.................: avg=20.36µs min=0s med=14µs max=32.36ms p(90)=20µs p(95)=21µs
http_req_tls_handshaking.........: avg=1.16ms min=0s med=0s max=183.1ms p(90)=0s p(95)=0s
http_req_waiting.................: avg=90.41ms min=80.85ms med=92.72ms max=542.86ms p(90)=96.77ms p(95)=102.74ms
http_reqs........................: 12960 215.658713/s
iteration_duration...............: avg=93.58ms min=81.05ms med=92.95ms max=1.83s p(90)=97.54ms p(95)=103.37ms
iterations.......................: 12953 215.542231/s
vus..............................: 20 min=20 max=21
vus_max..........................: 21 min=21 max=21
複制
由于所有内容都在一個腳本中,是以可以加強團隊之間的協作,并從浏覽器級别和協定級别的角度統一檢視性能名額。
參與其中
我們認為浏覽器自動化是 Web 應用程式測試的重要組成部分,我們對 xk6-browser 有很大的目标。我們的路線圖詳細說明了基本狀态更新以及我們的短期、中期和長期目标。
話雖如此,我們需要您的幫助!由于 xk6-browser 仍然相對較新,我們需要社群的幫助來試用該工具并向我們提供回報。
檢查我們的GitHub 項目,閱讀我們的文檔,并使用該工具。如果您發現任何問題,請在我們的 GitHub 項目上提出,或檢視我們的社群論壇以獲得更多支援。