Creating a Scala Project with Maven Dependency Management for Gatling Testing in IntelliJ IDEA

By | March 27, 2016

gatling_gun2

Gatling gun photo by Ryo Chijiiwa.

This article will, in two steps, show how to create a Scala project in IntelliJ IDEA in which we can develop and run Gatling load-simulations. The project will use Maven for dependency management and to run a selected Gatling simulation.
In the first step a Scala project that uses Maven for dependency management will be created and in the second step I will adapt the project to developing and running Gatling simulations.

Motivation

The following are my motivations for using Maven in connection to Scala and to create a project in the IntelliJ IDEA:

  • IntelliJ IDEA has good Scala code completion.
    I have tried the Scala IDE and while it is much easier to get Scala and Maven to play nice together, the code completion feature were not as good.
  • Maven is familiar for Java developers.
    Since this is part of an introduction of Gatling for Java developers, I want to minimize the number of unfamiliar events. In particular, I wanted to avoid the use of sbt.
  • Using Maven enables me to easily run a selected Gatling simulation from within the IDE.
    Gatling need to compile the simulation before being able to run it and the easiest way to accomplish this seems to me to use the Gatling Maven plug-in.
    Running the simulation from within the IDE allows for more rapid development of Gatling simulations.

Prerequisites

If you haven’t already, download IntelliJ IDEA – the community edition will do just fine for the purposes of this article. Having started IntelliJ IDEA, install the Scala plug-in as described here and then restart IntelliJ IDEA.
As we will rely on Maven for dependency management and run our Gatling  simulations from within the IDE, there is no need to download Gatling.
In addition, I assume that you have a recent version of the Java SE JDK installed and configured in the IDE. I have used version 1.8.0_73 in this article.

Update

The Scala maven archetype exists as a project on GitHub: https://github.com/davidB/scala-archetype-simple
If you chose to build the archetype from source and create a project using the local version of the archetype, then you can skip to step two.

Step One – The IntelliJ IDEA Scala Maven Project

In this first step a new Scala project will be created in IntelliJ IDEA that uses Maven for dependency management. This will be a general Scala project and can be used for any type of Scala development.

Find a Scala Maven Archetype

The Maven archetype I saw suggested in some places is quite old, so I went to Maven Central to look for something more recent. The most recent I was able to find was this archetype:

<groupId>net.alchim31.maven</groupId>
<artifactId>scala-archetype-simple</artifactId>
<version>1.6</version>

Create the Project

Armed with an archetype we are now ready to create the project in the IDE.

  • From the Menu, select File -> New -> Project…
  • On the left side of the New Project window, select Maven as the type of project to create.
  • At the top of the New Project window, select the Java SDK to be used by the project.
    As before, I will use 1.8.0_73 in this example but do chose a more recent version if available.
  • At the top of the New Project window, check the “Create from archetype” checkbox.
  • Click the Add Archetype… button in the upper-right side.
  • Enter group id, artifact id and version of the Scala Maven archetype found earlier and click  the OK button.
  • Select the archetype you just added in the archetype list.
    The New Project window should now look something like this:

    New Scala project with Maven archetype in IntelliJ IDEA

    New Scala project with Maven archetype in IntelliJ IDEA.

  • Click the Next button.
  • Enter the group id, artifact id and version of the new project.
    I use “se.ivankrizsan.gatling” for the group id, “gatling-examples” for the artifact id and “1.0.0-SNAPSHOT” for the version.
    Then click the Next button.
  • Review the Maven settings.
    If you, for instance, want to use another Maven installation or a settings.xml file for the new project, this is the time to change these settings.
    When you are finished, click the Next button.
  • Enter the project name and select a project location.
    Click the Finish button when you are done.
  • When the new project is opened, the IDE will present an alert saying that the project need to be imported.
    Click the Enable Auto-Import option.

Fix the Project pom.xml File

The archetype I have used in this example will not produce a project that is immediately runnable – we have to make some adjustments to the new project’s pom.xml file.

  • Update the <properties> element and its contents to look like this:
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <encoding>UTF-8</encoding>
        <scala.version>2.11.7</scala.version>
        <scala.compat.version>2.11</scala.compat.version>
    </properties>

    The maven.compiler.source and maven.compiler.target properties are chosen based upon the version of the Java JDK you use.
    I set the scala.version property to 2.11.7, since this is the version that Gatling is built on. Note that you may have to modify the scala.compat.version if you are using, for instance, Scala 2.12.x (which does not exist at the time of writing).

  • In the <build> element, remove the line containing “-make:transitive”, highlighted in this fragment from the pom.xml file.
    In the example below, I have already commented-out the line in question. This compilation-option will cause the compilation of Scala sources in the project to fail.

    <plugin>
        <!-- see http://davidb.github.com/scala-maven-plugin -->
        <groupId>net.alchim31.maven</groupId>
        <artifactId>scala-maven-plugin</artifactId>
        <version>3.2.0</version>
        <executions>
            <execution>
                <goals>
                    <goal>compile</goal>
                    <goal>testCompile</goal>
                </goals>
                <configuration>
                    <args>
                        <!-- REMOVE THIS LINE: <arg>-make:transitive</arg> -->
                        <arg>-dependencyfile</arg>
                        <arg>${project.build.directory}/.scala_dependencies</arg>
                    </args>
                </configuration>
            </execution>
        </executions>
    </plugin>
  • Update the test dependencies to look like below.
    If you are creating a project for exclusively for Gatling simulations, then this step can be skipped as these dependencies are not necessary in that case.
    The versions of these dependencies works with the Scala version used in this example but may require updates if a newer version of Scala is used.

    <!-- Test -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.specs2</groupId>
        <artifactId>specs2-core_${scala.compat.version}</artifactId>
        <version>3.7.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.specs2</groupId>
        <artifactId>specs2-junit_2.11</artifactId>
        <version>3.7.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.scalatest</groupId>
        <artifactId>scalatest_${scala.compat.version}</artifactId>
        <version>2.2.6</version>
        <scope>test</scope>
    </dependency>

We should now be able to right-click on the project root and select Run -> All Tests and the test should all succeed.

The complete pom.xml file at this stage looks like this:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>se.ivankrizsan.gatling</groupId>
    <artifactId>gatling-examples</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    
    <name>${project.artifactId}</name>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <encoding>UTF-8</encoding>
        <scala.version>2.11.7</scala.version>
        <scala.compat.version>2.11</scala.compat.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>${scala.version}</version>
        </dependency>

        <!-- Test dependencies. -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.specs2</groupId>
            <artifactId>specs2-core_${scala.compat.version}</artifactId>
            <version>3.7.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.specs2</groupId>
            <artifactId>specs2-junit_2.11</artifactId>
            <version>3.7.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.scalatest</groupId>
            <artifactId>scalatest_${scala.compat.version}</artifactId>
            <version>2.2.6</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <sourceDirectory>src/main/scala</sourceDirectory>
        <testSourceDirectory>src/test/scala</testSourceDirectory>
        <plugins>
            <plugin>
                <!-- see http://davidb.github.com/scala-maven-plugin -->
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>3.2.2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>testCompile</goal>
                        </goals>
                        <configuration>
                            <args>
                                <arg>-dependencyfile</arg>
                                <arg>${project.build.directory}/.scala_dependencies</arg>
                            </args>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
                <configuration>
                    <useFile>false</useFile>
                    <disableXmlReport>true</disableXmlReport>
                    <!-- If you have classpath issue like NoDefClassError,... -->
                    <!-- useManifestOnlyJar>false</useManifestOnlyJar -->
                    <includes>
                        <include>**/*Test.*</include>
                        <include>**/*Suite.*</include>
                    </includes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Step Two – The Gatling Load Simulation Project

In this second step we will modify the project that was created above so that we can develop and run Gatling load simulations.

More Modifications to the Project pom.xml File

The project’s pom.xml file need to be further modified:

  • Add the gatling.version and gatling-plugin.version properties, both having the value 2.1.7.
    Version 2.1.7 is, at the time of writing this article, the most recent release of Gatling.
    The complete <properties> element now looks like this:

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <encoding>UTF-8</encoding>
        <scala.version>2.11.7</scala.version>
        <scala.compat.version>2.11</scala.compat.version>
        <gatling.version>2.1.7</gatling.version>
        <gatling-plugin.version>2.1.7</gatling-plugin.version>
    </properties>
  • Add the Gatling test-dependency in the <dependencies> element.
    <dependency>
        <groupId>io.gatling.highcharts</groupId>
        <artifactId>gatling-charts-highcharts</artifactId>
        <version>${gatling.version}</version>
        <scope>test</scope>
    </dependency>
  • Add the Gatling plug-in in the <plugins> element in the <build> element.
    <!-- Gatling Maven plugin that runs the load-simulation. -->
    <plugin>
        <groupId>io.gatling</groupId>
        <artifactId>gatling-maven-plugin</artifactId>
        <version>${gatling-plugin.version}</version>
        <configuration>
            <simulationClass>se.ivankrizsan.gatling.simulations.HttpSimulation1</simulationClass>
        </configuration>
    </plugin>

    Note that there is a fully qualified class name in the <simulationClass> element. You will need to modify this in order to run the appropriate load simulation.
    For now, leave it as it is, since a load simulation to try out the project with will be supplied shortly.

Clean Up the Project (Optional)

In its current incarnation, the project will run both the regular Scala tests that were created by the artifact as well as Gatling load simulations using the mvn gatling:execute command.
However, if you only want to use the project to develop and run Gatling load simulations, I suggest cleaning up the project a bit.

  • In the project’s pom.xml file, remove the following dependencies:
    <!-- Test -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.specs2</groupId>
        <artifactId>specs2-core_${scala.compat.version}</artifactId>
        <version>3.7.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.specs2</groupId>
        <artifactId>specs2-junit_2.11</artifactId>
        <version>3.7.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.scalatest</groupId>
        <artifactId>scalatest_${scala.compat.version}</artifactId>
        <version>2.2.6</version>
        <scope>test</scope>
    </dependency>
  • In the <build> element in the pom.xml file, remove the surefire-plugin:
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.18.1</version>
        <configuration>
            <useFile>false</useFile>
            <disableXmlReport>true</disableXmlReport>
            <!-- If you have classpath issue like NoDefClassError,... -->
            <!-- useManifestOnlyJar>false</useManifestOnlyJar -->
            <includes>
                <include>**/*Test.*</include>
                <include>**/*Suite.*</include>
            </includes>
        </configuration>
    </plugin>
  • Also in the <build> element in the pom.xml file, remove the Scala compile plugin:
    <plugin>
        <!-- see http://davidb.github.com/scala-maven-plugin -->
        <groupId>net.alchim31.maven</groupId>
        <artifactId>scala-maven-plugin</artifactId>
        <version>3.2.2</version>
        <executions>
            <execution>
                <goals>
                    <goal>compile</goal>
                    <goal>testCompile</goal>
                </goals>
                <configuration>
                    <args>
                        <arg>-dependencyfile</arg>
                        <arg>${project.build.directory}/.scala_dependencies</arg>
                    </args>
                </configuration>
            </execution>
        </executions>
    </plugin>
  • In the project’s files in src/test/scala, delete the entire samples-package and its contents.
    In my project, there were three files: junit.scala, scalatest.scala and specs.scala.
  • In the terminal, run mvn clean to clean up the project.

The final version of the pom.xml file looks like this:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>se.ivankrizsan.gatling</groupId>
    <artifactId>gatling-examples</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    
    <name>${project.artifactId}</name>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <encoding>UTF-8</encoding>
        <scala.version>2.11.7</scala.version>
        <scala.compat.version>2.11</scala.compat.version>
        <gatling.version>2.1.7</gatling.version>
        <gatling-plugin.version>2.1.7</gatling-plugin.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>${scala.version}</version>
        </dependency>

        <dependency>
            <groupId>io.gatling.highcharts</groupId>
            <artifactId>gatling-charts-highcharts</artifactId>
            <version>${gatling.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <sourceDirectory>src/main/scala</sourceDirectory>
        <testSourceDirectory>src/test/scala</testSourceDirectory>
        <plugins>
            <!-- Gatling Maven plugin that runs the load-simulation. -->
            <plugin>
                <groupId>io.gatling</groupId>
                <artifactId>gatling-maven-plugin</artifactId>
                <version>${gatling-plugin.version}</version>
                <configuration>
                    <simulationClass>se.ivankrizsan.gatling.simulations.HttpSimulation1</simulationClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Try a Load Simulation

Finally we will try to run a Gatling load simulation in our project to see that it works as expected.

  • In src/test/scala, create a package named se.ivankrizsan.gatling.simulations.
  • In this package, create a Scala class named HttpSimulation1 with the following implementation.
    package se.ivankrizsan.gatling.simulations
    
    import io.gatling.core.Predef._
    import io.gatling.http.Predef._
    import io.gatling.http.config.HttpProtocolBuilder.toHttpProtocol
    import io.gatling.http.request.builder.HttpRequestBuilder.toActionBuilder
    
    /**
      * Example Gatling load test that sends two HTTP requests to the same URL.
      */
    class HttpSimulation1 extends Simulation {
    
        val theHttpProtocolBuilder = http
            .baseURL("https://computer-database.gatling.io")
    
        val theScenarioBuilder = scenario("Scenario1")
            .exec(
                http("myRequest1").get("/")
            )
    
        setUp(
            theScenarioBuilder.inject(atOnceUsers(1))
        ).protocols(theHttpProtocolBuilder)
    }
  • In the terminal in IntelliJ IDEA, run the mvn gatling:execute command.
    The result should be a build success. We will look at the results of Gatling load simulations in more detail in the next article on Gatling.

Happy coding!

3 thoughts on “Creating a Scala Project with Maven Dependency Management for Gatling Testing in IntelliJ IDEA

    1. Ivan Krizsan Post author

      Hello James!
      I do not recall having used the procedure described in the link. As far as I remember, I just installed the Scala plug-in in IntelliJ.
      Be aware of that I have never used Ivy.
      Happy coding!

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *