Automated Performance Tests using JMeter and Maven
Learning how to write and automate performance tests isn't easy. Perhaps that is why I have never actually wrote and automated performance tests; until now. For my latest open source side project, sass4j, I wanted to start the project with some automated performance tests. Since we were already using maven2, I wanted to find a maven2 plugin that allowed me to write complex performance tests and automate them easily in a continuous integration environment such as Hudson. Since I had heard good things about JMeter and there was an existing JMeter plugin, I decided on those technologies. Unfortunately the path this took me down was rather long and annoying, but I eventually figured everything out and that is the reason I would like to document the steps for others to reproduce in less time.
But first, why would anyone want to spend unnecessary time setting this up? The big advantage I think, is having the ability to compare nightly test results with a baseline and compare them with expectations. If my latest changes caused a major decrease in performance when I only added a few lines of code, then perhaps something is wrong. The second advantage is the sooner a performance issue is found the cheaper it costs to fix it. Think about the change set a developer has to look at if nightly performance tests were ran, compared to finding a performance issue 6 months from when the bug was introduced. With the former scenario, I only have to look at what has changed in the last 24 hours.
Now onto how to actually do this. I had two references in getting this done: The Official Apache JMeter Maven Plugin Site and a blog on AMIS by Robbrecht van Amerongen. Both of which are incomplete, but combined provide enough information.
Here is an outline of what you need to do. End to end this should take you about 15 minutes to setup; compared to the hours I spent I think you are getting a deal. Also you need to think about doing this in your artifactory server or company maven repository and not locally (doing it locally only helps you and not your entire company).
1) Download the JMeter maven bundle I created containing all the necessary artifacts
2) Install JMeter Plugin dependencies
3) Install the JMeter Plugin
4) Install JMeter
5) Update your maven project
6) Create jmx files and run mvn verify
The first 3 steps are necessary because there are specific dependencies the JMeter plugin requires that are not available on any public maven repo I can find, nor is the JMeter plugin.
1) Download the JMeter plugin bundle
- Click here to download the JMeter plugin zip file
- Unzip it
- cd to the extracted folder jmeter
- run the following mvn commands to deploy the jar files locally. Obviously update the location of your local maven2 repository and keep in mind the file paths are specific to linux. Again do this once in your company's maven repository.
- mvn deploy:deploy-file -DgroupId=org.apache.jmeter -DartifactId=jmeter -Dversion=2.2 -Dpackaging=jar -Dfile=jmeter-2.2.jar -DpomFile=jmeter-2.2.pom -Durl=file:///home/jlorenzen/.m2/repository/
- mvn deploy:deploy-file -DgroupId=jcharts -DartifactId=jcharts -Dversion=0.7.5 -Dpackaging=jar -Dfile=jcharts-0.7.5.jar -Durl=file:///home/jlorenzen/.m2/repository/
- mvn deploy:deploy-file -DgroupId=org.apache.jorphan -DartifactId=jorphan -Dversion=2.2 -Dpackaging=jar -Dfile=jorphan-2.2.jar -Durl=file:///home/jlorenzen/.m2/repository/
- mvn deploy:deploy-file -DgroupId=org.mozilla.javascript -DartifactId=javascript -Dversion=1.0 -Dpackaging=jar -Dfile=javascript-1.0.jar -Durl=file:///home/jlorenzen/.m2/repository/
- Unzip the maven-jmeter-plugin.zip file that was included in the JMeter plugin bundle.
- cd to the maven-jmeter-plugin folder
- run: mvn install
- This will install version 1.0 of the maven-jmeter-plugin. It's important we install a release verses a snapshot because you don't want your project to depend on snapshot plugins because this could have nasty side effects for building and releasing.
Now that you have the plugin installed you can actually start modifying your projects pom to use it. You first need to install JMeter because we will need a jmeter.properties file, some XSL files, and you are going to need it to create the .jmx files.
- Download and install JMeter
- Under your project create the directory: src/test/jmeter and src/test/resources
- Copy the jmeter.properties file from the JMeter bin folder to src/test/jmeter.
- Update the property jmeter.save.saveservice.output_format in the jmeter.properties file from csv to xml.
- Copy the files jmeter-results-detail-report_21.xsl and jmeter-results-report_21.xsl from the JMeter extras folder to src/test/resources
- Add the following to your POMs build/plugins section
<build>
<plugins>
<plugin>
<groupId>org.apache.jmeter</groupId>
<artifactId>maven-jmeter-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>jmeter-tests</id>
<phase>verify</phase>
<goals>
<goal>jmeter</goal>
</goals>
<configuration>
<reportDir>${project.build.directory}/jmeter-reports</reportDir>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<version>1.0-beta-2</version>
<executions>
<execution>
<phase>pre-site</phase>
<goals>
<goal>transform</goal>
</goals>
</execution>
</executions>
<configuration>
<transformationSets>
<transformationSet>
<dir>${project.build.directory}/jmeter-reports</dir>
<stylesheet>src/test/resources/jmeter-results-detail-report_21.xsl</stylesheet>
<outputDir>${project.build.directory}/site/jmeter-results</outputDir>
<fileMappers>
<fileMapper implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
<targetExtension>html</targetExtension>
</fileMapper>
</fileMappers>
</transformationSet>
</transformationSets>
</configuration>
</plugin>
</plugins>
</build>
6) Create jmx files and run mvn verify- Now use JMeter to create your .jmx files and place them under the src/test/jmeter directory.
- run: mvn verify to execute your performance tests
- run: mvn verify pre-site to execute your performance tests and produce the test results in an HTML report.
If you want to see a real example of this click here. Now the only step I am leaving out is actually automating it which isn't the hard part luckily. All you need to do in Hudson is create a new job and execute the mvn goals mvn verify to get them automated in a CI environment.

15 comments:
Cool...
I am wondering how would the jmeter test results would be displayed in Hudson... I've seen some cool findbug and cobertura reports in Hudson. Can you please post a snapshot of jmeter test results in hudson.
Sorry, but I haven't done that part of it. It wouldn't be too hard I imagine since other plugins are doing it.
hi there, i have followed your tutorial and everything worked out just fine.
the bad thing is that when i run mvn verify or something (doesnt matter what i run), i get this error:
Can't read log file
Embedded error: target/jmeter/jmeter.log (No such file or directory).
and the build fails, i tried to modify the jmeter.properties so it wont use that file but it keeps failing with the same error.
do you know what can i do?
well i found out what the problem was.
the jmeter.properties file, comes with the jmeter.log un-commented, all i have to do was comment it and everything worked out just fine.
thanks james for answering my mails
bye bye
I have been working with the JMeter Maven plugin for a recent project and have made some enhancements to it. For the project we wanted to run testNG tests by way of JMeter, as a part of our maven build process. To do that, we enhanced the way the JMeterMojo handles class loading, and wrote a custom JMeter/TestNG integration as well.
I'd like to contribute these changes back to... well someone. The JMeter project will likely accept the TestNG integration, but will not the new Maven mojo class since the original is not part of the JMeter project. In fact I can't find anywhere that is home for the JMeterMojo, outside of the wiki page.
I've been trying to locate the original contributor of the code (I think it's Tim McCune based on the jMeter wiki page), but with no luck so far.
Any ideas?
That is awesome. I love open source.
I think you have a couple of options, if you haven't done so already.
First, try and email any jmeter or maven2 mailing lists. Perhaps someone on those mailing lists will be able to help you out.
Outside of that, I think you have exhausted your options. I think its pretty obvious the jmeter maven plugin isn't your average open source project. Therefore, I think you would be justified in maybe open sourcing your plugin; even though I personally hate this, having two options to decided between and I believe it is frowned upon. Besides that you don't have any other choices.
If I remember correctly, the jmeter maven plugin was like only 1 class.
So here is what I would do if I were you. To ensure people use your plugin verses the original, make sure your maven mojo includes all the functionality of the original (and perhaps more). Once your plugin supports everything the original maven plugin does, plus your TestNG stuff, find a place to put it. I would recommend codehuas.org. There are alot of maven plugins out there and it would be the top one I would recommend. If not that one then googlecode or java.net. What you want are mailing lists, issue tracker, and a SCM, so your project doesn't suffer from the same mistakes of the original plugin.
Once that is all done, create your first 1.0 release and provide a download link with some examples. In the description of your project you can indicate the reasons why you created a second maven jmeter plugin.
Hope it helps and good luck.
Hello. Thanks for very useful article. But I have some problems:
Error in NonGUIDriver com.thoughtworks.xstream.converters.ConversionException: null
---- Debugging information ----
cause-exception : java.lang.reflect.UndeclaredThrowableException
cause-message : null
class : org.apache.jmeter.save.ScriptWrapper
required-type : org.apache.jmeter.save.ScriptWrapper
path : /org.apache.jmeter.save.ScriptWrapper/version
line number : 2
Version of my JMeter is 2.3 and jmx files differ from your example. Can you help me, please?
Hi
Cool tutorial - it works, but I have one problem the jmeter test do not terminate after "... end of run"
Any one know why?
/Peter
Hi
Fix to the hanging problem:
see:
http://wiki.apache.org/jakarta-jmeter/JMeterMavenPlugin
BTW: In my setting the transformation makes an extra entry in the table (equals to the first entry) - adding xalan 2.4.1 to the transformation plugins dependencies fix this problem.
/Peter
thanks for this post!
Nice tutorial, it helped me a lot. The only thing that isn't quite working are the xsl docs particularly the detailed one. the min and max values come out as NaN. I presume its because of some trnsfo9rmation in the style sheet, but I cannot see it. Does anyone else get this?
If I hadn't found this post I would probably have given up on using JMeter from Maven.
Now do you worried about that in the game do not had enough second life linden to play the game, now you can not worried, my friend told me a website, in here you can buy a lot linden dollars and only spend a little money, do not hesitate, it was really, in here we had much secondlife money, we can sure that you will get the cheap linden, quick to come here to buy lindens.
Now do you worried about that in the game do not had enough requiem gold to play the game, now you can not worried, my friend told me a website, in here you can buy a lot requiem lant and only spend a little money, do not hesitate, it was really, in here we had much requiem money, we can sure that you will get the cheap requiem lant, quick to come here to buy requiem online gold.
When i am using maven jmeter plugin for Java Request instead Http request i am getting below error.
Can any one have any idea plz..
Exception creating: jmeter.SampleClient java.lang.ClassCastException: jmeter.SampleClient cannot be cast to org.apache.jmeter.protocol.java.sampler.JavaSamplerClient
at org.apache.jmeter.protocol.java.sampler.JavaSampler.createJavaClient(JavaSampler.java:180)
at org.apache.jmeter.protocol.java.sampler.JavaSampler.sample(JavaSampler.java:159)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:247)
at java.lang.Thread.run(Thread.java:619)
If you are automating jmeter tests and comparing test runs, are you comparing stddev between runs?
Thanks, Martin.
Post a Comment