enriquezrene / gatling-tutorial-sbt Goto Github PK
View Code? Open in Web Editor NEWinitial import
initial import
When I'm writing a new simulation I'm currently duplicating code, particularly this snippet:
val httpProtocol = http
.baseURL("https://api.github.com")
.userAgentHeader("enriquezrene")
.acceptHeader("application/vnd.github.v3+json")
Done When:
Use this code for this project
Done When
Delete .idea folder from project
Done When
Include travis as part of the project
Implement looping with https://api.github.com/user/repos?page=2&per_page=1
Take a look on:
Advanced Tutorial
In this section, we assume that you have already gone through the Quickstart section and that you have a basic simulation to work with. We will apply a series of refactorings to introduce more advanced concepts and DSL constructs.
Step 01: Isolate processes
Presently our Simulation is one big monolithic scenario.
So first let us split it into composable business processes, akin to the PageObject pattern with Selenium. This way, you’ll be able to easily reuse some parts and build complex behaviors without sacrificing maintenance.
In our scenario we have three separated processes:
Search: search models by name
Browse: browse the list of models
Edit: edit a given model
We are going to extract those chains and store them into objects. Objects are native Scala singletons. You can create those in dedicated files, or directly in the same file as the Simulation.
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 = ???
}
We can now rewrite our scenario using these reusable business processes:
val scn = scenario("Scenario Name").exec(Search.search, Browse.browse, Edit.edit)
Step 02: Configure virtual users
So, this is great, we can load test our server with... one user! Let’s increase the number of users.
Let’s define two populations of users:
regular users: they can search and browse computer models.
admin users: they can search, browse and also edit computer models.
Translating into a scenario this gives:
val users = scenario("Users").exec(Search.search, Browse.browse)
val admins = scenario("Admins").exec(Search.search, Browse.browse, Edit.edit)
To increase the number of simulated users, all you have to do is to change the configuration of the simulation as follows:
setUp(users.inject(atOnceUsers(10)).protocols(httpConf))
Here we set only 10 users, because we don’t want to flood our test web application. Please, be kind and don’t crash our server ;-)
If you want to simulate 3000 users, you might not want them to start at the same time. Indeed, real users are more likely to connect to your web application gradually.
Gatling provides rampUsers to implement this behavior. The value of the ramp indicates the duration over which the users will be linearly started.
In our scenario let’s have 10 regular users and 2 admins, and ramp them over 10 seconds so we don’t hammer the server:
setUp(
users.inject(rampUsers(10) over (10 seconds)),
admins.inject(rampUsers(2) over (10 seconds))
).protocols(httpConf)
Step 03: Use dynamic data with Feeders and Checks
We have set our simulation to run a bunch of users, but they all search for the same model. Wouldn’t it be nice if every user could search a different model name?
We need dynamic data so that all users don’t play exactly the same scenario and we end up with a behavior completely different from the live system (due to caching, JIT etc.). This is where Feeders will be useful.
Feeders are data sources containing all the values you want to use in your scenarios. There are several types of Feeders, the most simple being the CSV Feeder: this is the one we will use in our test.
First let’s create a file named search.csv and place it in the user-files/data folder.
This file contains the following lines:
searchCriterion,searchComputerName
Macbook,MacBook Pro
eee,ASUS Eee PC 1005PE
Let’s then declare a feeder and use it to feed our users with the above data:
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)
}
Explanations:
First we create a feeder from a csv file with the following columns: searchCriterion, searchComputerName.
As the default feeder strategy is queue, we will use the random strategy for this test to avoid feeder starvation.
Every time a user reaches the feed step, it picks a random record from the feeder. This user has two new session attributes named searchCriterion, searchComputerName.
We use session data through Gatling’s EL to parametrize the search.
We use a CSS selector with an EL to capture a part of the HTML response, here a hyperlink, and save it in the user session with the name computerURL.
We use the previously saved hyperlink to get a specific page.
Note
For more details regarding Feeders, please check out Feeder reference page.
For more details regarding HTTP Checks, please check out Checks reference page.
Step 04: Looping
In the browse process we have a lot of repetition when iterating through the pages. We have four times the same request with a different query param value. Can we change this to not violate the DRY principle?
First we will extract the repeated exec block to a function. Indeed, Simulation‘s are plain Scala classes so we can use all the power of the language if needed:
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))
}
We can now call this function and pass the desired page number. But we still have repetition, it’s time to introduce another builtin structure:
object Browse {
val browse = repeat(5, "n") { // 1
exec(http("Page ${n}")
.get("/computers?p=${n}")) // 2
.pause(1)
}
}
This scenario should show how to save values inside the Galling session and how to recover them so that to use in subsequent requests
Done When
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.