Context:
You want to load test your application and get user response times including page rendering.
You usually use JMeter for load testing but the issue is that JMeter is not a real browser, so the reported response times do not include page rendering.
Hopefully, JMeter eco-system is very rich, so there is a solution for this, we will use:
- Selenium WebDriver to interact with Firefox
- JMeter WebDriver Sampler to call selenium from JMeter
Setting Up JMeter and Selenium WebDriver:
Setting up is very easy:
Download required libraries:
- Download JMeter 2.13 from here
- Download JMeter Plugins 1.3.1 (at the time of writing) from here, select:
- Standard bundle
- WebDriver bundle
- Firefox of course
Setup the bundle:
- Unzip jmeter bundle
- Unzip jmeter-plugins bundles
- Copy JMeterPlugins-WebDriver-1.3.1/lib/ext/JMeterPlugins-WebDriver.jar into jmeter/lib/ext
- Copy JMeterPlugins-Standard-1.3.1/lib/ext/JMeterPlugins-Standard.jar into jmeter/lib/ext
- Copy JMeterPlugins-WebDriver-1.3.1/lib/*.jar into jmeter/lib/
- As Webdriver dependencies conflict with 3 JMeter dependencies, see this Dev Mailing list thread, we need to remove the JMeter versions that are older, so remove:
- httpclient-4.2.6.jar
- httpcore-4.2.5.jar
- httpmime-4.2.6.jar
Use the correct Java version:
You need to run JMeter using Java 7 or 8 as JMeter Plugins requires it. As a side note, starting from next version of JMeter 3.0, Java 7 will be required.
Coding the scenario:
Our scenario will be composed of 3 steps:
- Visit Home Page of this blog
- Repeat 5 times:
- Search for a word
- Click on a link
Configure the Selenium Firefox Web Driver
We add “Firefox Driver Config” as a child of our new plan.
We only change one default, in Experimental tab we check “Development Mode” so that the Firefox instance does not quit at end of test so that we’re able to debug any issue.
Scenario overview
In our scenario, we use the following components:
- CSV DataSet to load variables containing the words to search from a CSV file. Variable will be named “searchWord”
- Loop Controller to iterate 5 times
- A Response Assertion to always test the presence of a text for each page
- Test Action with Duration set to 0 and a child containing a Gaussian Random Timer so that we can apply a think time exactly where we put the Test Action. Remember that Timers are scoped and are run before the Sample they are scoped within.
- View Results Tree only during scripting to debug the scrip
- View Results in Table to debug our Think Times
We end up with this:
Code “Home Page” Step
// We import java packages in Javascript
var pkg = JavaImporter(org.openqa.selenium)
var support_ui = JavaImporter(org.openqa.selenium.support.ui.WebDriverWait)
// We will timeout waits after 5 seconds
var wait = new support_ui.WebDriverWait(WDS.browser, 5000)
var conditions = org.openqa.selenium.support.ui.ExpectedConditions
// we start the timing
WDS.sampleResult.sampleStart()
try {
WDS.browser.get('http://www.ubik-ingenierie.com')
// we check that the element which id is headersearchform is loaded
wait.until(conditions.presenceOfElementLocated(pkg.By.id('headersearchform')))
// we end the timing
WDS.sampleResult.sampleEnd()
} catch(ex) {
WDS.sampleResult.sampleEnd()
WDS.sampleResult.setSuccessful(false);
WDS.sampleResult.setResponseMessage("Failed to load page, timeout occured");
}
Code “Search a Word” Step
var pkg = JavaImporter(org.openqa.selenium)
var support_ui = JavaImporter(org.openqa.selenium.support.ui.WebDriverWait)
var wait = new support_ui.WebDriverWait(WDS.browser, 5000)
var conditions = org.openqa.selenium.support.ui.ExpectedConditions
// We find the search icon by its class name "icon-search-1"
var searchIcon = WDS.browser.findElement(pkg.By.className('icon-search-1'))
// We click it
searchIcon.click()
// We ensure headersearchform element is clickable
wait.until(conditions.elementToBeClickable(pkg.By.id('headersearchform')))
// We find the search field by its id "s"
var searchField = WDS.browser.findElement(pkg.By.id('s'))
// We enter the parameter in WebDriver Sampler ${searchWord}
searchField.sendKeys([WDS.parameters])
// We find the headersearchsubmit button
var button = WDS.browser.findElement(pkg.By.id('headersearchsubmit'))
// We only start sampling here
WDS.sampleResult.sampleStart()
// We click on search
button.click()
WDS.sampleResult.sampleEnd()
Code “ClickOnBlog” Step
var pkg = JavaImporter(org.openqa.selenium);
var support_ui = JavaImporter(org.openqa.selenium.support.ui.WebDriverWait);
var wait = new support_ui.WebDriverWait(WDS.browser, 5000);
// We randomize a number lower than the number of links
var elements = WDS.browser.findElements(pkg.By.cssSelector("div.search-details > h5 > a"));
//var linkNumber = Math.floor((Math.random() * parseInt(WDS.parameters)));
WDS.log.info("link number="+elements.size());
var linkNumber = Math.floor(Math.random() * elements.size());
// As you can see on page,
if(linkNumber%2==0) {
linkNumber++;
}
WDS.log.info("linkNumber="+linkNumber);
// We find a random link to click
var link = WDS.browser.findElement(pkg.By.cssSelector(
'div.search-result:nth-child('+linkNumber+') > div:nth-child(2) > h5:nth-child(1) > a:nth-child(1)'))
WDS.sampleResult.sampleStart()
// We click on the link
link.click()
WDS.sampleResult.sampleEnd()
NDLR:
As you can see in this blog, using Selenium tests in JMeter is rather easy and allows you to reuse your Selenium Functional Testing for Load Testing.
We are now ready to run this test on our infrastructure.
Using Webdriver limits your capacity to scale due to its high usage of CPU as you nearly use 1 CPU core per every virtual user.
So the plan is to mix it with a regular JMeter load Test. This way, the regular JMeter Load Test will put enough load on your system while the JMeter WebDriver plan will allow you to get the user experienced response times including page rendering.
We will see in next blog how to scale WebDriver using the AWS Cloud very easily using Redline13 SAAS which comes at a very reasonable price and removes the burden of having to manage our load servers.
We will see all benefits we can get in terms of User Experience analysis.
Note that before running it on the cloud, we must uncheck in Experimental tab we check « Development Mode ».
About author:
Philippe Mouawad is a developer, committer and member of the JMeter Project Management Committee at Apache.
He is also the co-author of the book Master JMeter : from load testing to DevOps
He also works as an Architect and technical expert for Ubik-Ingenierie where he leads among other things the development of UbikLoadPack a set of Commercial Plugins for Apache JMeter allowing to load test different protocols like HLS, GWT, Flex.
About us:
- We provide professional services for Load Testing
- Our solutions Ubik Load Pack are used by Big players
- Get a Free trial
Recent Posts
- UbikLoadPack Video Streaming Plugin 9.1.5 14 June 2024
- What is DASH multi period and when to use it ? 4 December 2023
- UbikLoadPack Java Serialization Plugin 23 November 2023