December 19, 2016

Performance Testing with Gatling, Part 2

This is the second part of a two-part series covering theories on performance testing. This part showcases how to set up Gatling in IntelliJ. It provides some practical examples using Gatling, and explains how to get a graphical report for your execution results.

Sample Application

You can clone the sample application here: https://github.com/willhaben/gatling_part2

Setup

  1. Go to File -> New -> Project
  2. Create a new Project from Maven.
  3. Create from archetype and use the following infos
  4. On the next screen, enter your GroupId and ArtifactId. In our case it is 
    • GroupId: at
    • ArtifcatId: willhaben
  5. Enter a project name and create the project.

The pom.xml will be created automatically with all important dependencies. If you want to start the gatling tests from the command line, you have to add another plugin.

 <plugin>  
        <groupId>io.gatling</groupId>  
        <artifactId>gatling-maven-plugin</artifactId>  
        <version>2.2.1</version>
</plugin>  

Architecture

A simulation class must contain four different parts [1]
  1. The HTTP protocol configuration
  2. The headers definition
  3. The scenario definition
  4. The simulation definition
Based on that you can create any simulation.

Basic Simulation

In your src/test/scala folder, create a package called "simulations" and create a scala class, "MySimulations" which should extend "Simulation".

package simulations

import io.gatling.core.Predef._
import io.gatling.http.Predef._

class LoginSimulation extends Simulation {
  val httpConf = http.baseURL("http://localhost:8080")  //1
   .inferHtmlResources(BlackList(""".*\.css""", """.*\.js""", """.*\.ico""", """.*\.png""", """.*\.gif""", """.*\.svg""", """.*\.jpg"""))  //2
   .acceptHeader("*/*")  //3
   .acceptEncodingHeader("gzip, deflate, sdch") //3
   .acceptLanguageHeader("de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4")  //3
   .userAgentHeader("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36")  //3

   val scn = scenario("My Simulation")  //4
    .exec(  //5
        http("Frontpage")  //5
       .get("/")  //5
       .check(status.is(200))  //5
    )  
   setUp(
      scn.inject(atOnceUsers(1)) //6
   )  
   .protocols(httpConf)  //7
}

  1. The baseUrl points to the server which is running locally on my machine on port 8080.
  2. In this example, I will block many static resources, which i dont want to measure.
  3. Then, I set some common headers.
  4. Create a scenario with a name, which will be used in the reports.
  5. Define an execution step. In this example, I just do a GET and check if the response status is 200.
  6. In the setUp method, you have to declare which scenarios will be started during the simulation.
    • I also inject one user into the given scenario
  7. Use the http configuration during the simulation
In this example i just want to check if my startpage is responding with a http status code 200. The scenario should run just one time and for just one user. To try your scenario for different users who are requesting the page at different times you can change "atOnceUsers(1)" to "rampUsers(10) over (10 seconds)". Then every 10 seconds a new user will request the startpage.

Basic Form Simulation

Lets build up a short user journey. The user goes on your startpage fills in some credentials at the login form and pushes the login button.

 object Startpage {  
   val getStartpageRequest = exec(http("Startpage")  
    .get("http://localhost:8080")  
    .check(status.is(200)))  
  }  

  object Login {  
   val postLoginRequest = exec(http("Login Request")  
    .post("/login")  
    .headers(headers_1)  
    .formParam("firstName", "Some")  
    .formParam("password", "SomePass")   
  }  

   val headers_1 = Map("Content-Type" -> """application/x-www-form-urlencoded""")  
  
   val scn = scenario("Login Simulation")  
    .exec(Startpage.getStartpageRequest) 
    .pause(10)
    .exec(Login.postLoginRequest)  

   setUp(scn.inject(atOnceUsers(1)))  
   .protocols(httpConf)  


The same httpConf as in the previous example will be used. For better readability it is recommended that you group the requests into objects, which here are "Startpage" and "Login". You can then chain the execution of both requests as seen in the scenario definition. During these two requests, i want to simulate that the user has paused his action, during this time, he is perhaps searching for the login form.

How to run the tests

Run the test on the command line with "mvn gatling:execute". You, will see some results already in the command line, but to see the graphical report, you have to go in your project folder into "target/gatling/" to see the results of each run. For that just open the index.html in your run scenario folder.

Overwrite the Gatling config

If you want to customize Gatling it gives you the option to overwrite a lot of config values using your own. Just put the overriding gatling.conf file into your resources directory. For example, if you would like to override where the test results are stored, you can overwrite the "outputDirectoryBaseName" value and use the directory of your choice.

 gatling {  
  core {  
   #outputDirectoryBaseName = "" # The prefix for each simulation result folder (then suffixed by the report generation timestamp)  
   #runDescription = ""     # The description for this simulation run, displayed in each report  
   #encoding = "utf-8"      # Encoding to use throughout Gatling for file and string manipulation  

It is also possible to change how the charts are created, therefore you would change the values in the charting section.

 charting {  
   #noReports = false    # When set to true, don't generate HTML reports  
   #maxPlotPerSeries = 1000 # Number of points per graph in Gatling reports  
   #useGroupDurationMetric = false # Switch group timings from cumulated response time to group duration.  
   indicators {  
    #lowerBound = 800   # Lower bound for the requests' response time to track in the reports and the console summary  
    #higherBound = 1200  # Higher bound for the requests' response time to track in the reports and the console summary  
    #percentile1 = 50   # Value for the 1st percentile to track in the reports, the console summary and Graphite  
    #percentile2 = 75   # Value for the 2nd percentile to track in the reports, the console summary and Graphite  
    #percentile3 = 95   # Value for the 3rd percentile to track in the reports, the console summary and Graphite  
    #percentile4 = 99   # Value for the 4th percentile to track in the reports, the console summary and Graphite  
   }  
  }  

Summary

Gatling is really easy to use and can provide you with an easy to use API. This was just a basic example of how to use Gatling, but you can create much more complex pieces of code. For example, you can run scenarios with users who have different kinds of roles, or you can use different types of data sources, such as .csv files, to load data that you can use for requests, to name just a few.

[1] : http://gatling.io/docs/2.2.3/general/simulation_structure.html


5 comments:

  1. A good article, thank you! Here is a link to wikipedia that may come in handy abd there is a link to the article by
    college paper service. It is interesting to read, check it.

    ReplyDelete
  2. AnonymousMay 26, 2017

    I have noticed a different kind of coding languages are present on the web and more developers are present in the marker and they have different kind of developers’ expert who have more experience on a particular language in which they have a command. Usually coding languages info is also present on the web where anyone can access even there a higher education facility to each one and there anyone can continue his/her basic education is present for the each one. And there anyone can enroll at http://www.degreeforlifeexperience.com/ for completing higher education easily.

    ReplyDelete
  3. One of the challenges for financial planners in dealing with Baby Boomers approaching their actual (hoped-for) retirement dates has to do with assisting them in addressing their oft-substantial debt loads. Carrying debt has long been a fact of life for Americans, as taking out loans to pay for life's "finer things" has become not only more fashionable, but a standard practice. Gone, for example, are the days when significant numbers of people would expect to wipe out their home mortgages before they actually retire; a desire to continue to improve the size and quality of one's residence, as well as...http://www.careerpanth.xyz/

    ReplyDelete