Type mismatch. Required: Validation[PopulationBuilder] => NotInferredA, found: PopulationBuilder

Hello I’m unable to complete Tutorial C8 for Scala + IntelliJ :frowning:

my code reads as follows (I don’t really know why at the end of my setUp method it shows :PopulationBuilder underlined in red

I also tried rampDuration.seconds as recommended in the tutorial but no luck.

Thanks

package gatlingdemostore

import scala.concurrent.duration._
import io.gatling.core.Predef._
import io.gatling.core.structure.ChainBuilder
import io.gatling.http.Predef._
import io.gatling.http.check.HttpCheckScope.Status
import io.gatling.jdbc.Predef._

import scala.util.Random

class Demostore extends Simulation {

	val domain = "demostore.gatling.io"

	val httpProtocol = http
		.baseUrl("https://" + domain)

	def userCount: Int = getProperty("USERS", "10").toInt
	def rampDuration: Int = getProperty("RAMP_DURATION", "20").toInt
	def testDuration: Int = getProperty("DURATION", "30").toInt

	private def getProperty(propertyName: String, defaultValue: String) = {
		Option(System.getenv(propertyName))
			.orElse(Option(System.getProperty(propertyName)))
			.getOrElse(defaultValue)
	}



	val categoryFeeder = csv("data/categoryDetails.csv").random
	val jsonFeederProducts = jsonFile("data/productDetails.json").random
	val csvFeederLoginDetails = csv("data/loginDetails.csv").circular

	val rnd = new Random()

	def randomString(length: Int): String = {
		rnd.alphanumeric.filter(_.isLetter).take(length).mkString
	}

	val initSession = exec(flushCookieJar)
		.exec(session => session.set("randomNumber", rnd.nextInt)) //create a random number using the method above
		.exec(session => session.set("customerLoggedIn", false)) // set customer login to false
		.exec(session => session.set("cartTotal", 0.00)) //
		.exec(addCookie(Cookie("sessionId", randomString(10)).withDomain(domain)))
		//.exec { session => println(session); session}

	object CmsPages {
		def homepage = {
			exec(http("Load Home Page")
				.get("/")
				.check(status.is(200))
				.check(regex("<title>Gatling Demo-Store</title>").exists)
				.check(css("#_csrf", "content").saveAs("csrfValue"))
			)
		}

		def aboutUs = {
			exec(http("Load About Us Page")
				.get("/about-us")
				.check(status.is(200))
				.check(substring("About Us"))
			)
		}
	}

	object Catalog {
		object Category {
			def view: ChainBuilder = {
				feed(categoryFeeder)
					.exec(http("Load Category Page - ${categoryName}")
						.get("/category/${categorySlug}")
						.check(status.is(200))
						.check(css("#CategoryName").is("${categoryName}"))
					)
			}
		}

		object Product {
			def view: ChainBuilder = {
				feed(jsonFeederProducts)
					.exec(http("Load Product Page - ${name}")
						.get("/product/${slug}")
						.check(status.is(200))
						.check(css("#ProductDescription").is("${description}"))
					)
			}


			def add: ChainBuilder = {
				exec(view).
					exec(http("Add Product to Cart ")
						.get("/cart/add/${id}")
						.check(status.is(200))
						.check(substring("items in your cart"))
					)
					.exec(session => {
						val currentCartTotal = session("cartTotal").as[Double]
						val itemPrice = session("price").as[Double]
						session.set("cartTotal", (currentCartTotal + itemPrice))
					})
			}
		}
	}

	object Customer {
		def login = {
			feed(csvFeederLoginDetails)
				.exec(http("Load Login Page")
					.get("/login")
					.check(status.is(200))
					.check(substring("Username"))
				)
				.exec {session => println(session); session}
				.exec(http("Customer Login Action")
					.post("/login")
					.formParam("_csrf", "${csrfValue}")
					.formParam("username", "${username}")
					.formParam("password", "${password}")
					.check(status.is(200))
				)
				.exec(session => session.set("customerLoggedIn", true))
		}
	}

	object Checkout {
		def viewCart = {
			doIf(session => !session("customerLoggedIn").as[Boolean]){
				exec(Customer.login)
			}
			.exec(http("Load Cart Page")
			.get("/cart/view")
				.check(status.is(200))
				.check(css("#grandTotal").is("$$${cartTotal}"))
			)
		}

		def completeCheckout = {
			exec(http("Checkout cart")
				.get("/cart/checkout")
				.check(status.is(200))
				.check(substring("Thanks for your order! See you soon!"))
			)
		}
	}

	val scn = scenario("Demostore")
		.exec(initSession)
		.exec(CmsPages.homepage)
		.pause(2)
		.exec(CmsPages.aboutUs)
		.pause(2)
		.exec(Catalog.Category.view)
		.pause(2)
		.exec(Catalog.Product.add)
		.pause(2)
		.exec(Checkout.viewCart)
		.pause(2)
		.exec(Checkout.completeCheckout)

	object UserJourneys {
		def minPause = 100.milliseconds

		def maxPause = 500.milliseconds

		def browseStore = {
			exec(initSession)
				.exec(CmsPages.homepage)
				.pause(maxPause)
				.exec(CmsPages.aboutUs)
				.pause(minPause, maxPause)
				.repeat(5) {
					exec(Catalog.Category.view)
						.pause(minPause, maxPause)
						.exec(Catalog.Product.view)
				}
		}

		def abandonCart = {
			exec(initSession)
				.exec(CmsPages.homepage)
				.pause(maxPause)
				.exec(Catalog.Category.view)
				.pause(minPause, maxPause)
				.exec(Catalog.Product.view)
				.pause(minPause, maxPause)
				.exec(Catalog.Product.add)
		}

		def completePurchase = {
			exec(initSession)
				.exec(CmsPages.homepage)
				.pause(maxPause)
				.exec(Catalog.Category.view)
				.pause(minPause, maxPause)
				.exec(Catalog.Product.view)
				.pause(minPause, maxPause)
				.exec(Catalog.Product.add)
				.pause(minPause, maxPause)
				.exec(Checkout.viewCart)
				.pause(minPause, maxPause)
				.exec(Catalog.Product.add)
		}
	}

	object Scenarios {
		def default = scenario("Default Load Test")
			.during(testDuration seconds) {
				randomSwitch(
					75d -> exec(UserJourneys.browseStore),
					15d -> exec(UserJourneys.abandonCart),
					10d -> exec(UserJourneys.completePurchase)
				)
			}

		def highPurchase = scenario("High Purchase Load Test")
			.during(60) {
				randomSwitch(
					25d -> exec(UserJourneys.browseStore),
					25d -> exec(UserJourneys.abandonCart),
					50d -> exec(UserJourneys.completePurchase)
				)
			}
	}

	setUp(
		Scenarios.default
			.inject(rampUsers(userCount) during (rampDuration seconds)).protocols(httpProtocol)
			.andThen(
				Scenarios.highPurchase
					.inject(rampUsers(5) during (10 seconds)).protocols(httpProtocol)
			)
	)

}

The 10 seconds syntax (postfix operator notation) is deprecated and IntelliJ reports it as an error by default (you can enable it back in the Scala Compiler configuration in IntelliJ) but things would work from the command line.

The best way is to switch to the modern syntax: 10.seconds with a dot.

Quick question: why aren’t you going with the Java DSL instead?

I’ve changed the code as below but no luck. Apologies if I’m missing something obvious but I’m new to coding.

To answer your second question I’ve been doing the tutorial with Scala but now that Java is available I will look to start my actual tests with this as I believe Java is a much more commonly used language.

	setUp(
		Scenarios.default
			.inject(rampUsers(userCount) during (rampDuration.seconds)).protocols(httpProtocol)
			.andThen(
				Scenarios.highPurchase
					.inject(rampUsers(5) during (10.seconds)).protocols(httpProtocol)
			)
	)

Can’t say. Your simulation just works on my side. Which version of Scala have you configured in IntelliJ?

Scala 4.38. No probs. I’ll continue with the tutorial and hopefully when I migrate over to Java it will be fine. Thanks for your help mate.

Scala 4.38

I’m not referring to the version of the Scala plugin for IntelliJ but the version of the Scala library itself. I suspect you’re not using the correct version matching your version of Gatling. Gatling 3.7 requires Scala 2.13 and won’t work with Scala 2.12 nor 3.

I’m not sure how to find the version of the scala library. I can see the gatling version in the pom.xml. I tried running scala -version in terminal but got an error.

?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.myGatlingTest</groupId>
  <artifactId>gatling-demostore</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <encoding>UTF-8</encoding>

    <gatling.version>3.3.1</gatling.version>
    <gatling-maven-plugin.version>3.0.5</gatling-maven-plugin.version>
  </properties>

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

  <build>
    <!-- so that maven compiles src/test/scala and not just src/test/java -->
    <testSourceDirectory>src/test/scala</testSourceDirectory>
    <plugins>
      <plugin>
        <!-- so that maven can create a jar -->
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.2.0</version>
      </plugin>

      <!-- this plugin is so maven can compile your scala code -->
      <plugin>
        <groupId>net.alchim31.maven</groupId>
        <artifactId>scala-maven-plugin</artifactId>
        <version>4.3.1</version>
        <executions>
          <execution>
            <goals>
              <goal>testCompile</goal>
            </goals>
            <configuration>
              <recompileMode>all</recompileMode>
              <jvmArgs>
                <jvmArg>-Xss100M</jvmArg>
              </jvmArgs>
              <args>
                <arg>-target:jvm-1.8</arg>
                <arg>-deprecation</arg>
                <arg>-feature</arg>
                <arg>-unchecked</arg>
                <arg>-language:implicitConversions</arg>
                <arg>-language:postfixOps</arg>
              </args>
            </configuration>
          </execution>
        </executions>
      </plugin>

      <!-- so maven can build a package for FrontLine -->
      <plugin>
        <groupId>io.gatling.frontline</groupId>
        <artifactId>frontline-maven-plugin</artifactId>
        <version>1.0.3</version>
        <executions>
          <execution>
            <goals>
              <goal>package</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <!-- This plugin allows us to run a gatling test through Maven from the command line -->
      <plugin>
        <groupId>io.gatling</groupId>
        <artifactId>gatling-maven-plugin</artifactId>
        <version>${gatling-maven-plugin.version}</version>
      </plugin>
    </plugins>
  </build>
</project>

This is a very old now unsupported config for Gatling Enterprise. Could you please explain where you’ve found this configuration? Where do you use Gatling Enterprise? Direct contract? AWS or Azure MarketPlace?

I’m not entirely sure but looking in my browser history I have a feeling it might have been from here but could be wrong GitHub - gatling/gatling-academy-module-2

Looks like I should start from scratch with the JAVA DSL

I’ll delete the existing folder I have and create a new one. Should I remove/change anything else too.

I don’t have Gatling Enterprise.

  1. Run your first tests with Gatling - Java
  2. Gatling Academy

Cheers buddy. I did everything completely wrong when learning performance testing.

  1. Unofficial youtube tutorial - realised that it is not official and old
  2. Started the Scala tutorial - now just realised that I’m using an old config :laughing:

I’ll get cracking!