I have to write some tests with Gatling / Scala. In my concrete case I have to login to a website with username and password (additionally there is also keycloak security). There is a CSV file with a lot of user/password lines and my goal is to login with every single user/password out of this CSV file.
The problem is I do not know how to do that. I am able to login with username/password and the security token of the keycloak with just one user. That's fine so far, but not enough. Here is what I have done so far.
The first class:
class LasttestBestand extends Simulation {
val context = Context.ladeContext("de", "integ")
val userCredentials = TestdatenImport.ladeTestDaten("de")
val httpProtocol = http
.baseUrl(s"${context.protocol}://${context.host}")
.inferHtmlResources(
BlackList(""".*\.css""", """.*\.js""", """.*\.ico""", """.*\.woff"""),
WhiteList()
)
.acceptHeader("application/json, text/plain, */*")
.acceptEncodingHeader("gzip, deflate")
.acceptLanguageHeader("de,en-US;q=0.7,en;q=0.3")
.disableFollowRedirect
.userAgentHeader(
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:63.0) Gecko/20100101 Firefox/63.0"
)
val scn = scenario("Lasttest Bestand")
.feed(userCredentials.csvFeeder)
.exec(Login.holeAccessToken("${Benutzername}", "${Passwort}", context))
.exec(Suche.ladeKundensucheResourcen(context))
setUp(
scn.inject(
atOnceUsers(1)
)
).protocols(httpProtocol)
}
The feeder class:
class TestdatenImport(val csvFeeder: BatchableFeederBuilder[String]) {}
object TestdatenImport {
def ladeTestDaten(land: String) = {
val csvFeeder = csv(s"data/eca-bb3-${land}-testdaten.csv").circular
new TestdatenImport(
csvFeeder
)
}
}
The Login:
object Login {
def holeAccessToken(
benutzer: String,
passwort: String,
context: Context
): ChainBuilder = {
val keycloakUri = s"${context.protocol}://${context.keycloakHost}"
val redirectUri =
s"${context.protocol}%3A%2F%2F${context.host}%2Fapp%2F%3Fredirect_fragment%3D%252Fsuche"
exec(
http("Login Page")
.get(
s"$keycloakUri/auth/realms/${context.realm}/protocol/openid-connect/auth"
)
.queryParam("client_id", "bestand-js")
.queryParam("redirect_uri", redirectUri)
.queryParam("state", UUID.randomUUID().toString())
.queryParam("nonce", UUID.randomUUID().toString())
.queryParam("response_mode", "fragment")
.queryParam("response_type", "code")
.queryParam("scope", "openid")
.header(
"Accept",
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
)
.header("Upgrade-Insecure-Requests", "1")
.check(status.is(200))
.check(
css("#kc-form-login")
.ofType[Node]
.transform(variable => {
variable.getAttribute("action")
})
.saveAs("loginUrl")
)
).exec(
http("Login")
.post("${loginUrl}")
.formParam("username", benutzer)
.formParam("password", passwort)
.header(
"Accept",
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
)
.header("Upgrade-Insecure-Requests", "1")
.check(status.is(302))
.check(
header("Location")
.transform(url => {
url.substring(url.indexOf("code=") + 5, url.length())
})
.saveAs("code")
)
.check(header("Location").saveAs("nextPage"))
)
.exec(
http("Fetch Token")
.post(
s"$keycloakUri/auth/realms/${context.realm}/protocol/openid-connect/token"
)
.header("Accept", "*/*")
.header("Origin", s"${context.protocol}://${context.host}")
.formParam("code", "${code}")
.formParam("grant_type", "authorization_code")
.formParam("client_id", "bestand-js")
.formParam("redirect_uri", redirectUri)
.check(status.is(200))
.check(
jsonPath("$..access_token")
.saveAs("accessToken")
)
)
}
}
As you can see I added a feeder to the scenario, but I do not know how to "repeat" the login the number of times there are user/password lines in the CSV file. What do I do wrong?
Inject as many users as you have entries in your CSV file, eg:
scn.inject(
rampUsers(numberOfEntries) during(10 minutes)
)