Example of advanced performance script
A test script I wrote that exercised logic and features of JMeter and Rational Performance Tester (RPT) was a dynamic catalog browse in WebSphere Commerce. Most performance test scripts are a fixed sequence of parameterized HTTP requests but this scenario involved designing something different.
This technique can be applied to traversing a website that has a “tree” structure where navigating “downwards” eventually leads to a final page.
Consider the following six steps to browse a catalog from homepage to product display in the WebSphere Commerce starter store "Aurora".
On each page, the next step is a url link revealed by Chrome browser with right-click and "inspect". The parentheses part of a regular expression captures the url link relative to the hostname.
1) Open the url to the Commerce store and click on “Site Map” in the footer of the homepage
The regular expression to find the Site Map link is
id="footerSiteMapLink" href="http.{0,1}://.*?(/.*?)"
2) On the sitemap page, choose a top level category such as TopCategory3
The regular expression for a top level category url is
SiteMap_[0-9]+_[0-9]+_[0-9]+_-[0-9]+_[0-9]+.*?href="http.{0,1}://[^/]+([^"]+)"
3) TopCategory3 has further subcategories on the sidebar.
The regular expression for a subcategory url is
id="SBN_.*?href="http.{0,1}://[^/]+(/[^"]+)"
4) The second level category has third level categories
The regular expression is the same for finding further subcategories
id="SBN_.*?href="http.{0,1}://[^/]+(/[^"]+)"
5) The third level category has no more subcategories and only lists products
The regular expression for a product url on the page is
id="WC_CatalogEntryDBThumbnailDisplayJSPF[^"]+"\s+href="http.{0,1}://[^/]+(/[^"]+)"
6) The product display at the end of browsing
If one records these steps in RPT or JMeter, this what the hard coded script looks like (excluding static content such as images)
We could use a data set in RPT or CSV Data Set Config in JMeter to parameterize what categories and products are browsed. However, the script becomes tightly coupled to data and may not work when the catalog is modified or points to a different store. It is better to have the test script dynamically determine the available catalog links and traverse until it reaches a product. This is possible when the page design uses distinct ids for the URLs and does not have circular references during catalog depth traversal. We can approach the browse with the following pseudo code:
categoryURL=null
productURL=null
visit homepage
find and visit sitemap
categoryURL=extract random top level category URL using regex
while categoryURL !=null
visit categoryURL
categoryURL=extract random subcategory URL using regex
productURL=extract random product url using regex
end while
if productURL!=null
visit productlink
RPT test design
1. Setup two variables for CategoryURL and ProductURL and initialize to “none”
2. Visit Homepage and Sitemap
3. Create a reference on SiteMap response to extract a random topcategory and assign value to CategoryURL
4a. Setup an infinite loop with condition (4b) and customcode to break out if CategoryURL is equal to none. The custom code calls tes.getLoopControl().breakLoop();
5. Visit CategoryURL
6. Create a reference on category content response to extract a random category url and assign value to CategoryURL
Create a reference on category content response to extract a random product url and assign value to ProductURL
7. If the category content response has no categories explicitly CategoryURL to "none"
8. If ProductURL is not equal to “none” then visit it
JMeter test design
SiteMap is parsed for a CategoryURL
The next four elements determine if CategoriesLoop should be entered
1. If Controller with condition, "${CategoryURL}" != "false"
2. Beanshell sampler, vars.put("Loop1","true");
3. If Controller with condition, "${CategoryURL}" == "false”
4. Beanshell sampler, vars.put("Loop1","false”);
5. While controller with condition, ${Loop1}
The while loop traverses subcategories until no more categories are found.
If the CategoryURL extractor cannot find any urls it is set to false which will allow the loop to exit by setting the loop condition to false
6. If Controller with condition, "${CategoryURL}" == “false"
7. Beanshell sampler, vars.put("Loop1","false”);
8. If Controller with condition, "${ProductURL}" != “false"
If a productURL exists then it will be visited