如何在加特林中从参数化仿真中获取每个方案的报告?

时间:2018-06-20 06:28:33

标签: gatling scala-gatling

我正在尝试测试一个基于输入在内部执行不同操作的API:

  • 国家
  • 客户
  • 项目数量

以下是我的模拟结果:

val countries = List("US", "CAN")
val customerTypes = List("TYPE1", "TYPE2")
val basketSizes = List(1, 10, 50)

val scenarioGenerator: Seq[(String, String, Int)] = for {
  country <- countries
  customerType <- customerTypes
  basketSize <- basketSizes
} yield (country, customerType, basketSize)

def scenarios(): Seq[PopulationBuilder] = {
  var scenarioList = new ArraySeq[PopulationBuilder](countries.size * customerTypes.size * basketSizes.size)
  var i = 0;
  for ((country: String, customerType: String, basketSize: Int) <- scenarioGenerator) {
    // fetch customer data for scenario
    val customers = DataFetcher.customerRequest(country, customerType)
    // fetch product data for scenario
    val products = DataFetcher.productRequest(country)

    // generate a scenario with given data and parameters
    val scen = scenario(s"Pricing-(${country},${customerType},${basketSize})")
      // feeder that creates the request object for the gatling user
      .feed(new PricingFeeder(country, customers, products, basketSize))
      .repeat(10) {
        exec(Pricing.price)
          .pause(500 milliseconds)
      }
      .inject(
        rampUsers(10) over (10 seconds)
      )
    scenarioList(i) = scen

    i = i + 1
  }

  scenarioList
}

setUp(scenarios: _*).protocols(httpProto)

这是与maven插件一起运行的(并使用gatling插件对jenkins进行了跟踪),但是这导致了一个单独的跟踪情况:Pricing。这是没有用的,因为即使项目数量接近响应时间的线性增长。

simulation.log包含每种方案类型的数据,但是开箱即用的报告将其作为一种查询类型进行处理,并将所有结果合并到一个图形中,这意味着无法查看是否某种组合会由于计算或数据错误而导致峰值。

我想为每种组合获取单独的指标,因此很容易看到例如API的代码或数据更改在Pricing-(US,TYPE1,50)场景中导致了延迟高峰。 / p>

通过加特林实现这一目标的惯用方式是什么?我不想为每种情况创建模拟,因为这将是一场噩梦(要设法通过jmeter摆脱手动管理的数据和jenkins作业是我们想要实现的目标。)

1 个答案:

答案 0 :(得分:0)

第一件事-在一个模拟中运行这么多场景不是一个好习惯,因为它不按顺序并行运行它们,因此您应该确保它是您想要的。

如果是这样,您可以利用加特林报告允许按组显示图的事实。因此,您可以将所有请求包装在基于参数命名的组中,这样,在报告的详细视图中,您可以选择要显示的组,例如:

 val singleScenario = scenario(s"Pricing-(${country},${customerType},${basketSize})")
   .group(s"Pricing-(${country},${customerType},${basketSize})"){
      .feed(new PricingFeeder(country, customers, products, basketSize))
        .repeat(10) {
          exec(Pricing.price)
            .pause(500 milliseconds)
        }
    }

如果您不需要所有方案都可以并行运行,并且希望为单独的方案提供单独的报告,则最好的方法是将模拟类实现为参数化的抽象类,并为每个参数集添加单独的类,例如在加特林中,一次模拟等于报告,fe。:

package com.performance.project.simulations

import io.gatling.core.Predef.Simulation
import scala.concurrent.duration._

class UsType1Simulation1 extends ParametrizedSimulation("US", "TYPE1", 1)
class UsType1Simulation10 extends ParametrizedSimulation("US", "TYPE1", 10)
class UsType1Simulation50 extends ParametrizedSimulation("US", "TYPE1", 50)

class UsType2Simulation1 extends ParametrizedSimulation("US", "TYPE2", 1)
class UsType2Simulation10 extends ParametrizedSimulation("US", "TYPE2", 10)
class UsType2Simulation50 extends ParametrizedSimulation("US", "TYPE2", 50)

class CanType1Simulation1 extends ParametrizedSimulation("CAN", "TYPE1", 1)
class CanType1Simulation10 extends ParametrizedSimulation("CAN", "TYPE1", 10)
class CanType1Simulation50 extends ParametrizedSimulation("CAN", "TYPE1", 50)

class CanType2Simulation1 extends ParametrizedSimulation("CAN", "TYPE2", 1)
class CanType2Simulation10 extends ParametrizedSimulation("CAN", "TYPE2", 10)
class CanType2Simulation50 extends ParametrizedSimulation("CAN", "TYPE2", 50)

sealed abstract class ParametrizedSimulation(country: String, customerType: String, basketSize: Int) extends Simulation{

  val customers = DataFetcher.customerRequest(country, customerType)
  val products = DataFetcher.productRequest(country)

  val singleScenario = scenario(s"Pricing-(${country},${customerType},${basketSize})")
    .feed(new PricingFeeder(country, customers, products, basketSize))
    .repeat(10) {
      exec(Pricing.price)
      .pause(500 milliseconds)
    }
    .inject(
      rampUsers(10) over (10 seconds)
    )

  setUp(singleScenario).protocols(httpProto)
}

当然,只有在组合数量很少的情况下才有意义,数百种组合会变得凌乱。