Skip to content

qualersoft/jmeter-gradle-plugin

Repository files navigation

jmeter-gradle-plugin

General

jmeter gradle plugin custom%2B17788%2Fgithub.com%2Fqualersoft%2Fjmeter gradle plugin

Main

badge main badge

Develop

badge develop badge

Gradle plugin to integrate JMeter™ tests into the gradle ecosystem.
This plugin arose from the need of a simple to start, but easy to customize plugin. The current available plugins are either hardwired to older JMeter™ version or configuration is not so well documented.

Usage

Applying the plugin

Kotlin DSL
plugins {
  id("de.qualersoft.jmeter") version "<latest>"
}
Groovy DSL
plugins {
  id 'de.qualersoft.jmeter' version '<latest>'
}

Customization

The easiest way to customize the plugin is via its jmeter extension.
The extension offers the following properties

jmeter {
  systemPropertyFiles // (1)
  systemProperties // (2)
  mainPropertyFile // (3)
  additionalPropertyFiles // (4)
  jmeterProperties // (5)
  customReportTemplate // (6)
  globalPropertiesFile // (7)
  globalProperties // (8)

  proxxScheme // (9)
  proxyHost // (10)
  proxyPort // (11)
  nonProxyHosts // (12)

  logConfig // (13)
  logOutputFile // (14)

  jmxRootDir // (15)
  resultDir // (16)
  reportDir // (17)
  maxHeap // (18)
  jvmArgs //(19)

  enableRemoteExecution // (20)
  exitRemoteServers // (21)
}
Details
  1. Additional system property file(s).

  2. Define additional system properties.

  3. The jmeter property file to use.

  4. Additional JMeter property file(s).

  5. Define additional JMeter properties.

  6. Path to a custom report-template folder used by report generator.

  7. Path to a JMeter property file which will be sent to all servers.

  8. Properties which will be sent to remote servers.

  9. Scheme of the proxy (e.g. for non-http).

  10. Proxy server hostname or ip address.

  11. Proxy server port.

  12. Non-proxy hosts (e.g *.apache.org).

  13. Custom log configuration file (currently log4j2)
    Defaults to bundled configuration.

  14. File where jmeter log will be written to.
    Defaults to <buildDir>/logs/jmeter.log

  15. Used to search for jmx files.
    Defaults to src/test/jmeter

  16. Directory to which the jtl-files will be written.
    Defaults to <buildDir>/test-results/jmeter

  17. Root directory where to put the reports
    Defaults to <buildDir>/reports/jmeter

  18. [Optional] Specifies the maximum heap size the JVM process will start with.

  19. [Optional] additional JVM arguments that will be passed to the jvm directly.

  20. [Optional] tells JMeter™ to run the tests on the configured remote-servers (see remoting)
    Defaults to false.

  21. [Optional] Flag to exit remote servers at the end of the test. Only effective iff enableRemoteExecution is true.
    Defaults to false.

These configurations will be applied to all tasks (where appropriate) and can be overridden or extended on a per task base.

Quickstarter

Important
To use the quickstarter you must have gradle installed and available on your path

Running a jmeter-test

  1. In a folder of your choice (referred to as root), execute:

    root> gradle init --dsl kotlin --type basic

    This brings up the setup. We are going to create a basic project and using Kotlin as build script DSL.

  2. Create the following folder structure (gradle stuff from 1. left out)

    root
    ├── src
    │   └── test
    │       └── jmeter
    │           └── Test.jmx (1)
    └── build.gradle.kts (2)
    1. default folder for jmx-files is src/test/jmeter
      You can copy the Test.jmx from functional test resources

    2. build.gradle.kts is generated by gradle; we need it in next step.

  3. Put the following into build.gradle.kts

    import de.qualersoft.jmeter.gradleplugin.task.* // (1)
    
    plugins {
      id("de.qualersoft.jmeter") version "<latest>" // (2)
    }
    
    repositories {
      mavenCentral() // (3)
    }
    
    tasks {
      register<JMeterRunTask>("runJMeter") { // (4)
        jmxFile.set("Test.jmx") // (5)
      }
    }
    1. Import task package. (to save some typing later on 😋)

    2. Apply the plugin. (Don’t forget to correct the version 😉)

    3. We need a repository to retrieve jmeter-library. mavenCentral should work in almost any case.

    4. Register a run-task and give it a name (if we wouldn’t had imported the task package in (1), we would have to use the full qualified path)

    5. Configure the task to use our test.jmx file under src/test/jmeter

  4. Run it by opening a cli of your choice in root

    root> ./gradlew runJMeter
    Output
    ...
    Starting standalone test @ Sat Sep 04 18:53:51 CEST 2021 (1630774431340)
    Waiting for possible Shutdown/StopTestNow/HeapDump/ThreadDump message on port 4445
    Warning: Nashorn engine is planned to be removed from a future JDK release
    summary =     30 in 00:00:03 =   10,0/s Avg:   206 Min:   108 Max:   345 Err:     2 (6,67%)
    Tidying up ...    @ Sat Sep 04 18:53:55 CEST 2021 (1630774435185)
    ... end of run
    
    BUILD SUCCESSFUL in 15s
    1 actionable task: 1 executed

👏 Congratulations, you’ve run your first jmeter script with this plugin.
🎉 4 steps, that’s it. Simple, wasn’t it?

Generating a report

After you’ve run your first jmeter script successfully, you might want to have a report showing some nice charts and stats.

No problem, just:

  1. add the following to your build.gradel.kts s task section

    tasks {
      register<JMeterRunTask>("runJMeter") {
        jmxFile.set("Test.jmx")
      }
    
      register<JMeterReportTask>("jmeterReport") { // (1)
        jmxFile.set("Test.jmx") // (2)
      }
    }
    1. registering a JMeterReportTask task (remember the include? Now it pays off 😊)

    2. by pointing it to our jmx file the plugin knows where to find everything

  2. back in CLI run

    root> ./gradlew jmeterReport

    This generates the report under build/reports/jmeter/Test

    ℹ️
    Note
    The directory 'Test' is retrieved from the jmx-file’s name.

🎉 Voila, just 2 steps to get a report.

Remark that to generate a report, you have to execute the runJMeter task before. There are two ways you can get it in one rush.

  1. Declare a dependsOn in report task

    register<JMeterReportTask>("jmeterReport") {
      jmxFile.set("Test.jmx")
      dependsOn("runJMeter")
    }

    if you now execute jmeterReport, runJMeter get executed first if required

  2. Or let the 'run' task always generate a report with generateReport flag

    register<JMeterRunTask>("runTest") {
      jmxFile.set("Test.jmx")
      generateReport = true
    }
    💡
    Tip
    If you are going to rerun the task without cleaning outputs you will get an error because the report already exists. In such cases just enable the deleteResults property

Want to modify the jmx-Script with jmeter UI?

No problem, just add the following task to your build-script

tasks {
  register<JMeterGuiTask>("edit") {
    jmxFile.set("Test.jmx")
  }
}

And back to CLI

root> ./gradlew edit

As an alternative, if you don’t want to clutter your tasks-section, you can use the jmeter-extension

jmeter {
  withGuiTask("edit") {
    jmxFile.set("Test.jmx")
  }
}

Cli arguments

All tasks also provide some of their properties through cli-arguments.
To see what arguments are supported by a task simply run

root> ./gradlew help --task <taskName> (1)
  1. with <taskName> being a JMeter*Task defined in your build script. E.g. our 'runTest' task from above.

Configure jmeter

As mentioned in the preamble, this plugin is designed to be as flexible as possible.
By that, the used jmeter runner artifact as well as plugins or libraries aren’t hardwired but can be configured.

Configure the runner

You can easily configure not only the version but also its coordinates. All this can be done through the jmeter.tool property.

jmeter {
  tool {
    group // (1)
    name // (2)
    version // (3)
    mainConfigureClosure // (4)
    mainClass // (5)
  }
}
Details
  1. The group-id of the jmeter-runner.
    Defaults to 'org.apache.jmeter'.

  2. The name (artifact-id) of the jmeter-runner.
    Defaults to 'ApacheJMeter'.

  3. the version of the jmeter-runner.
    Defaults to '5.5'.

  4. A closure/lambda to configure the dependency any further.
    Will only applied if not null (which is the default).

  5. The main class used to execute the jmeter runner.
    Defaults to 'org.apache.jmeter.NewDriver'.

Adding plugins

Because the runner itself is quite useless without any plugins you can add them with the jmeterPlugin dependency handler

dependencies {
  jmeterPlugin("org.jmeter:a-plugin:1.2.3") // (1)
}
  1. Resolves the 'a-plugin' and puts its artifact into /lib/ext, transitive dependencies will be put to lib directory.

ℹ️

By default, this plugin includes the following plugins (as they are also default plugins in a normal JMeter installation):

"bolt", "components", "core", "ftp", "functions", "http", "java", "jdbc", "jms", "junit", "ldap", "mail", "mongodb", "native", "tcp"

Info

At the current time, these plugins are hardwired and cannot be modified.
(Yeah, I know, so much about flexibility…​ Mea culpa! 😉)

Adding support libraries

Sometimes you have quite special and reusable code that you wouldn’t maintain within JMeter. Or you just want to use an existing libraries functions within JMeter.
To make them available to JMeter you can use the jmeterLibrary dependency handler

dependencies {
  jmeterLibrary("org.apache.commons:commons-csv:1.9.0") // (1)
}
  1. Resolves the 'commons-csv' artifact and puts its artifact, and all its transitive dependencies, under /lib directory.

ℹ️
🔥
Internal only

Within an IDE with autocomplete, you may also notice the jmeterRunner dependency handler. This is for internal use only! Please use the respective jmeter.tool properties to configure the runner.

Pitfalls when using jmeter-dependencies/-plugins

Some of the jmeter dependencies or plugins, which you want to apply through jmeterLibrary or jmeterPlugin might depend on 'org.apache.jmeter:bom'. This dependency seems not available on any maven-repository (for further information refer to Issue 64465). If you are affected by this issue, you will see an error message similar to

...
> Could not resolve all dependencies for configuration ':jmeterPlugin'.
> Could not find org.apache.jmeter:bom:5.5.
Required by:
    project > ...

when executing one of the jmeter-tasks. As a convenient workaround, the jmeter-gradle-plugin provides the jmeter.tool.applyBomWorkaround function. You can apply it to the affected dependencies like this:

dependencies {
  // in case a library is affected
  jmeterLibrary("org.apache.jmeter:a-library:1.2.3") {
    jmeter.tool.applyBomWorkaround(this)
  }

  // or in case a plugin is affected
  jmeterPlugin("org.jmeter:a-plugin:1.2.3") {
    jmeter.tool.applyBomWorkaround(this)
  }
}