在本節中,咱們假設您已經經過了「快速入門」部分,而且有一個基本的模擬可使用。 咱們將應用一系列重構來引入更先進的概念和DSL結構。css
步驟01:隔離進程
目前咱們的模擬是一個大的總體場景。html
因此首先讓咱們把它分解成可組合的業務流程,相似於Selenium的PageObject模式。 這樣,您就能夠輕鬆地重用一些零件並構建複雜的行爲,而不會犧牲維護。java
在咱們的方案中,咱們有三個分離的過程
搜索:按名稱搜索模型
瀏覽:瀏覽模型列表
編輯:編輯給定的模型
咱們將提取這些鏈並將其存儲在對象中。 對象是原生Scala單身。 您能夠建立專用文件,或直接在與模擬相同的文件。緩存
object Search { val search = exec(http("Home") // let's give proper names, as they are displayed in the reports .get("/")) .pause(7) .exec(http("Search") .get("/computers?f=macbook")) .pause(2) .exec(http("Select") .get("/computers/6")) .pause(3) } object Browse { val browse = ??? } object Edit { val edit = ??? }
咱們如今可使用這些可重用的業務流程重寫咱們的場景服務器
val scn = scenario("Scenario Name").exec(Search.search, Browse.browse, Edit.edit)
步驟02:配置虛擬用戶session
咱們能夠加載測試咱們的服務器與...一個用戶! 咱們增長用戶數量。dom
咱們來定義兩個用戶羣:
普通用戶:他們能夠搜索和瀏覽電腦型號。
管理員用戶:他們能夠搜索,瀏覽和編輯電腦型號。
翻譯成這樣一個場景:函數
val users = scenario("Users").exec(Search.search, Browse.browse) val admins = scenario("Admins").exec(Search.search, Browse.browse, Edit.edit)
要增長模擬用戶的數量,您只須要更改模擬的配置以下:post
setUp(users.inject(atOnceUsers(10)).protocols(httpConf))
在這裏,咱們只設置了10個用戶,由於咱們不想flood咱們的測試Web應用程序。 請,善待,不要崩潰咱們的服務器;-)測試
若是要模擬3000個用戶,您可能不但願它們同時啓動。 事實上,真正的用戶更有可能逐漸鏈接到您的Web應用程序。
Gatling提供了用戶來實現這一行爲。 斜坡值表示用戶線性啓動的持續時間。
在咱們的場景中,咱們有10個常規用戶和2個管理員,並將它們運行10秒,因此咱們不會破壞服務器:
步驟03:使用Feeders和Checks的動態數據
咱們已經將咱們的模擬設置爲運行一大堆用戶,但他們都搜索相同的模型。 若是每一個用戶均可以搜索不一樣的型號名稱,那不是很好嗎?
咱們須要動態數據,以便全部用戶不會徹底相同的場景,咱們最終會發現與實時系統徹底不一樣的行爲(因爲緩存,JIT等)。 這是Feeders將會有用的地方。
Feeders是包含您想在場景中使用的全部值的數據源。 有幾種類型的饋線,最簡單的是CSV Feeder:這是咱們在測試中使用的。
首先咱們建立一個名爲search.csv的文件,並將其放在user-files / data文件夾中。
此文件包含如下行:
searchCriterion,searchComputerName Macbook,MacBook Pro eee,ASUS Eee PC 1005PE
object Search { val feeder = csv("search.csv").random // 1, 2 val search = exec(http("Home") .get("/")) .pause(1) .feed(feeder) // 3 .exec(http("Search") .get("/computers?f=${searchCriterion}") // 4 .check(css("a:contains('${searchComputerName}')", "href").saveAs("computerURL"))) // 5 .pause(1) .exec(http("Select") .get("${computerURL}")) // 6 .pause(1) }
說明:
首先,咱們從一個csv文件中建立一個feed,其中包含如下列:searchCriterion,searchComputerName。
因爲默認feed策略是隊列,所以咱們將採用隨機策略進行這次測試,以免進feed不足。
每次用戶到達進紙步驟時,它會從進紙器中選擇一個隨機記錄。 該用戶有兩個新的會話屬性,名爲searchCriterion,searchComputerName。
咱們經過Gatling的EL使用會話數據來參數搜索。
咱們使用帶有EL的CSS選擇器來捕獲HTML響應的一部分,這裏是超連接,並將其保存在名爲computerURL的用戶會話中。
咱們使用之前保存的超連接來獲取特定的頁面。
注意:
有關feed的更多詳細信息,請參閱Feeder參考頁面。
有關HTTP檢查的更多詳細信息,請參閱檢查參考頁面。
步驟04:循環
在瀏覽過程當中,咱們在遍歷頁面時會有不少重複。 咱們有四次相同的請求,具備不一樣的查詢參數值。 咱們能夠改變這一點,不違反DRY原則嗎?
首先咱們將提取重複的exec塊到一個函數。 的確,Simulation是普通的Scala類,因此若是須要,咱們可使用語言的全部權力:
object Browse { def gotoPage(page: Int) = exec(http("Page " + page) .get("/computers?p=" + page)) .pause(1) val browse = exec(gotoPage(0), gotoPage(1), gotoPage(2), gotoPage(3), gotoPage(4)) }
咱們如今能夠調用此函數並傳遞所需的頁碼。 可是咱們仍是重複,如今是引進另外一個內置結構的時候了:
object Browse { val browse = repeat(5, "n") { // 1 exec(http("Page ${n}") .get("/computers?p=${n}")) // 2 .pause(1) } }
重複內建是在運行時解決的循環。 它須要重複次數和可選的存儲在用戶會話中的計數器的名稱。
當咱們強制計數器名稱時,咱們能夠在Gatling EL中使用它,並訪問第n頁。
有關循環的更多詳細信息,請參閱循環參考頁面。
步驟05:檢查和故障管理
到目前爲止,咱們只使用檢查來從html響應中提取一些數據並將其存儲在會話中。 可是檢查也是方便檢查響應的屬性。 默認狀況下,Gatling會檢查http響應狀態是否爲20x或304。
爲了展現故障管理,咱們將對隨機失敗的條件進行檢查:
import java.util.concurrent.ThreadLocalRandom // 1 val edit = exec(http("Form") .get("/computers/new")) .pause(1) .exec(http("Post") .post("/computers") .check(status.is(session => 200 + ThreadLocalRandom.current.nextInt(2)))) // 2
說明:
首先咱們導入ThreadLocalRandom來生成隨機值。
咱們對使用lambda定製的條件進行檢查。 每次用戶執行請求並隨機返回200或201時,將進行評估。響應狀態爲200時,檢查將隨機失敗。
爲了處理這個隨機失敗,咱們使用tryMax和exitHereIfFailed結構以下:
val tryMaxEdit = tryMax(2) { // 1 exec(edit) }.exitHereIfFailed // 2
說明:
tryMax嘗試給定塊達n次。 這裏咱們最多嘗試兩次。
若是全部嘗試失敗,用戶將退出整個場景因爲exitHereIfFailed。
注意
有關條件塊的更多詳細信息,請參閱條件語句參考頁面。