k6是GitHub上提供的開源負載測試工具。它是用Go編寫的,並運行用JavaScript編寫的測試腳本。它受到了開發人員,測試人員和DevOps團隊的強烈興趣,並擁有超過4400名GitHub明星。k6是命令行驅動的,測試結果輸出到stdout或結果分析工具,如Load Impact Insights。
JMeter也是一個開源負載測試工具,已存在多年。它非常受歡迎,擁有數千名用戶。它是一個Java應用程序,JMeter GUI用於創建測試腳本。此外,一些腳本語言可用於編寫JMeter函數,包括Java,Groovy和JavaScript。Groovy已成為推薦的默認選項。但是,只能從命令行執行負載測試運行。
在“大衛與歌利亞”的方式中,讓我們看一下在k6中比在JMeter中更容易做的事情的幾個例子。
1.在變量中保存HTTP響應
在JMeter中:
-
添加Beanshell Postprocessor作為請求的子項,返回您要查找的響應。
-
將代碼
vars.put(“response”, new String(data));
放入PostProcessor的“腳本”區域。 -
請根據
${response}
需要參考提取的值 。
在k6中,使用以下測試腳本代碼:
let response = http.get(“http://javame.cnblogs.com/”);
在這兩種情況下,數據最終都在響應變量中。主要區別在於您必須在JMeter中向請求添加Beanshell PostProcessor,然后才能添加代碼段。
2.測試預期的404響應
在JMeter中:
在測試下創建一個新的Response Assertion。在斷言的“要測試的響應字段”部分中,確保選中“忽略狀態”框。
然后,您可以添加其他斷言,例如將“要測試的響應字段”中的無線電設置為“響應代碼”,並將“要測試的模式”設置為404。
圖1:顯示如何設置響應斷言的JMeter GUI。
在k6中,使用以下測試腳本代碼:
let response = http.get(“http://some.url/”); check(res, { "Status is 404": (r) => r.status === 404 });
這里的主要區別在於,在JMeter中執行此操作需要您單擊GUI並在輸入字段中填入值,而使用k6則需要編寫幾行代碼。您可以在版本控制系統(VCS)中輕松跟蹤和管理k6 JavaScript加載測試代碼,就像您的應用程序代碼一樣。
3.在不同的測試中重用自定義測試代碼
例如,假設您要調用logTransaction()
150個不同測試配置中的一個文件中定義的 函數。
在JMeter中:
-
將該行添加
beanshell.sampler.init=BeanShellSampler.bshrc
到user.properties文件(位於JMeter安裝的“bin”文件夾中)。 -
將logTransaction函數放在BeanShellSampler.bshrc文件中(相同位置,JMeter的“bin”文件夾)。
-
下次啟動JMeter時,您可以在任何腳本中從任何Beanshell Sampler調用該函數。
在k6:
-
將logTransaction()函數放在JavaScript文件中,例如“logTransaction.js”
-
使用以下語句在任何腳本中導入該函數:從“/path/to/logTransaction.js”導入{logTransaction};
在k6中,任何Javascript文件都可以直接用作可導入模塊,它允許您以任何方式組織文件。您還可以直接通過網絡導入模塊:
import { logTransaction } from "s3.amazonaws.com/path/to/logTransaction.js";
除了標准的ES6 JavaScript API之外,k6還捆綁了API來處理Cookie,加密,編碼,環境變量,HTML表單,HTML解析,多部分請求,TLS客戶端證書,TLS密碼和版本等等。
4.實現嵌套循環
例如,您可能希望使用兩個參數測試servlet:X和Y,其中X和Y是0到100之間的隨機數。您需要一個嵌套循環,如下所示:
for(int x = 0 ; x <= 100 ; x ++) for(int y = 0 ; y <= 100 ; y ++) servlet ?param1 = x &param2 = y
在JMeter中:
您的架構可能如下所示:
Thread Group User Defined Variables maxX = 100 maxY = 100 Loop Controller X Loop Count: ${__BeanShell(Integer.parseInt(vars.get("maxX"))+1)} Counter X Start: 0 Increment: 1 Maximum: ${maxX} Reference Name: loopX Loop Controller Y Loop Count: ${__BeanShell(Integer.parseInt(vars.get("maxY"))+1)} Counter Y Start: 0 Increment: 1 Maximum: ${maxY} Reference Name: loopY YOUR HTTP Request servlet?param1=${loopX}¶m2=${loopY} . . .
在k6:
使用以下腳本代碼:
for(var x = 0 ; x <= 100 ; x ++) for(var y = 0 ; y <= 100 ; y ++) http.get(“http://some.domain/servlet?param1 =”+ x +“¶m2=”+ y);
當然,執行更復雜的邏輯分支是基於GUI的方法與直接在代碼中編寫邏輯相比經常變得非常笨重的地方。k6解決方案與用於描述問題的偽代碼非常相似。
5.進行並行請求
我們通常希望並行發出多個請求,就像瀏覽器在獲取網頁時所做的那樣。這使得服務器上的壓力比每個虛擬用戶一次只發出一個請求要多得多。
在JMeter中:
JMeter提供同步計時器,允許對請求進行分組,以便它們可以在同一時刻執行。只需在測試計划中添加同步計時器,並確保:
-
它在兩個請求中都處於同一級別
-
線程組中的虛擬用戶數> = =同步計時器中設置的數量
在k6:
使用此
http.batch()
功能可並行發出多個請求。例如:http.batch([ "http://test.loadimpact.com", "http://test.loadimpact.com/style.css", "http://test.loadimpact.com/images/logo.png" ]);
上述“解決方案”不具有100%的可比性。在JMeter情況下,我們仍然只允許每個虛擬用戶(VU)一次發出一個請求。這意味着JMeter VU不是“真實用戶”的完全准確模型。單個人類用戶將使用他們的Web瀏覽器同時發出多個請求,而JMeter VU一次只發出一個請求。
相反,JMeter所做的是同步VU,以便它們在同一時間發出請求。(對我來說似乎不太有用 - 總吞吐量可能會下降,因為某些VU必須等待其他VU完成請求)。
另一方面,在所示的示例中,k6將允許每個VU打開三個並發TCP連接,因此能夠並行獲取這三個項目,就像Web瀏覽器一樣。這意味着在k6情況下,100個VU可以並行獲取300個項目。在Jmeter情況下,100 VU將並行獲取100個項目。(注意:還有一個名為Parallel Controller的 JMeter擴展可用於創建並行請求)。
推薦閱讀: