• Gatling-HTTP 脚本模板


    import io.gatling.commons.validation._
    import io.gatling.core.check.Validator
    import io.gatling.core.Predef._
    import io.gatling.http.Predef.{http, _}
    
    import scala.concurrent.duration._
    
    class DemoSimulation extends Simulation {
    
      // 支持多种格式的csv
      val csvFeeder = csv("foo.csv") // use a comma separator
      val tsvFeeder = tsv("foo.tsv") // use a tabulation separator
      val ssvFeeder = ssv("foo.ssv") // use a semicolon separator
      val customSeparatorFeeder = separatedValues("foo.txt", '#') // use your own separator
    
      // 一次加载所有数据
      val csvFeeder1 = csv("foo.csv").eager.random
    
      // 批量加载数据,默认2000
      val csvFeeder2 = csv("foo.csv").batch.random
      // 修改默认buffer
      val csvFeeder3 = csv("foo.csv").batch(200).random
    
      val feeder = csv("search.csv").random
    
      // 可进行全局配置
      val httpProtocol = http
        // .enableHttp2 // 支持http2
        .warmUp("http://www.baidu.com") // 热机,启动客户端的http(默认访问的是https://gatling.io,但是这个地址往往不通)
        .baseUrl("http://www.baidu.com", "http://www.baidu.com", "http://www.baidu.com") // 支持多个地址,绕过负载均衡,直接向服务器施加压力
        .header("key", "value")
        .connectionHeader("close")
        .disableCaching
    
      // 创建场景
      val scn_1 = scenario("scn_1").during(1 minutes) {
        exec(
          feed(feeder).exec(
            http("http_1")
              .get("/")
              .queryParam("key", "value")
    
              /** http协议常用的检查点设置 **/
              .check(
    
              /** Targets the HTTP response status code. **/
              status.is(200),
              status.in(200, 304),
              status.not(404),
    
              // 以下所有关于正则的查找,都支持:find、find(occurrence)、findAll、findRandom、findRandom(num: Int)、findRandom(num: Int, failIfLess = true)、count
    
              /** Targets the current page absolute URL. Useful when following redirects in order to check if the landing page is indeed the expected one. **/
              currentLocation.validate(new StringValidator[String](CheckType.equals, "http://www.baidu.com/")), // 可以检查有没有出现重定向。
              currentLocationRegex("www").validate(new StringValidator[String](CheckType.equals, "www")), // 支持正则匹配,取出关键字。
              // currentLocationRegex("http://(www).(baidu).(com)").ofType[(String, String, String)].validate(todo),  // 支持多个匹配,这个时候Option[T]是Option[(String, String, String)],StringValidator需要重新适配。
    
              /** Targets the HTTP response header of the given name.  **/
              header("connection").validate(new StringValidator[String](CheckType.equals, "close")),
              headerRegex("Set-Cookie", "delPer=(.+?);").validate(new StringValidator[String](CheckType.equals, "0")),
              // headerRegex("FOO", "foo(.*)bar(.*)baz").ofType[(String, String)].validate(todo),  // 同样支持多个匹配
    
              /** Returns the response time of this request in milliseconds = the time between starting to send the request and finishing to receive the response. **/
              responseTimeInMillis.lte(1000),
    
              /** Return the full response body String. Note that this can be matched against content from the the filesystem using RawFileBody or ElFileBody. **/
              bodyString.validate(new StringValidator[String](CheckType.contains, "百度")),
    
              /** bodyBytes 和 bodyStream 应该用不到吧 **/
    
              /** Scans for the indices of a given substring inside the body string. **/
              substring("baidu"), // same as substring("baidu").find.exists
              substring("baidu").findAll.saveAs("indices"), // 可以保存到session中(保存为一个Seq序列)
              substring("baidu").count.gte(10), // 可以检查某正则条件出现的次数
    
              // 官网描述,substring 似乎比 regex 更节省CPU资源,推荐使用 substring
    
              /** 正则匹配 **/
              regex("""<link rel="dns-prefetch" href="//(.+?)"/>""").find.validate(new StringValidator[String](CheckType.contains, "com")), // 默认查询第一个
              regex("""<link rel="dns-prefetch" href="//(.+?)"/>""").find(0).validate(new StringValidator[String](CheckType.contains, "com")), // 可以指定查询第几个
              regex("""<link rel="dns-prefetch" href="//(.+?)"/>""").findRandom.validate(new StringValidator[String](CheckType.contains, "com")), // 随机匹配一个
              // regex("""<link rel="dns-prefetch" href="//(.+?)"/>""").findAll.validate(new StringValidator[String](CheckType.contains, "www")), // 这个返回是一个Seq[String],需要单独写Validator
              regex("""<link rel="dns-prefetch" href="//(.+?)"/>""").count.gte(5),
    
              /** XPath匹配 **/
              // xpath("//input[@id='text1']/@value"),
    
              /** JSON匹配 **/
              // jsonPath("$..foo.bar[2].baz").ofType[Int]  // 支持 ofType[Int] 进行类型转换
            )
          ))
      }
    
      val scn_2 = scenario("scn_2").forever() {
        exec(
          /** form **/
          http("http_1")
            .post("/")
            .formParam("myKey", "myValue")
            .formParamSeq(Seq(("myKey", "myValue"), ("anotherKey", "anotherValue"))) // 批量
            .formParamMap(Map("myKey" -> "myValue", "anotherKey" -> "anotherValue")) // 这样也可以
            .multivaluedFormParam("multi1", "${foo}") // 一个key对应多个value。where foo is the name of a Seq Session attribute
            .multivaluedFormParam("multi2", session => List("foo", "bar")), // 这样也可以
    
          /** from 上传文件 **/
          http("http_upload")
            .post("my.form-action.uri")
            .formParam("myKey", "myValue")
            .formUpload("myKey2", "myAttachment.txt"),
    
          /** row格式 **/
          http("http_row")
            .body(RawFileBody("myFileBody.json")).asJson // { "myContent": "myHardCodedValue" }
            .body(ElFileBody("myFileBody.json")).asJson // { "myContent": "${myDynamicValue}" },将会解析myDynamicValue的具体值
            .body(StringBody("""{ "myContent": "${myDynamicValue}" }""")).asJson // 将会解析myDynamicValue的具体值
            .body(StringBody(session => """{ "myContent": """" + someGenerator(session) + """" }""")).asJson // TODO
            // .body(ByteArrayBody(bytes: Expression[Array[Byte]]))
            // .body(InputStreamBody(stream: Expression[InputStream]))
            .body(PebbleStringBody("""{ "myContent": "{% if myCondition %}{{myDynamicValue}}{% endif %}" }""")).asJson // 支持一些复杂的逻辑
            .body(PebbleFileBody("myFileBody.json")).asJson, // 可以使用文件中的内容
    
          /** 支持模拟浏览器的并行获取资源 **/
          http("http_resources")
            .get("https://www.github.com/gatling/gatling/issues")
            .resources(
              http("api.js").get("https://collector-cdn.github.com/assets/api.js"),
              http("ga.js").get("https://ssl.google-analytics.com/ga.js")
            )
        )
      }
    
      // 开始执行
      setUp(
        scn_1.inject(atOnceUsers(1)),
        scn_2.inject(atOnceUsers(1))
      ).protocols(httpProtocol)
    }
    
    /**
      * 自定义的字符串检查方法
      *
      * @param checkType
      * @param param
      * @tparam A
      */
    class StringValidator[A](checkType: String, param: String) extends Validator[A] {
    
      val name = "StringValidator"
    
      def apply(actual: Option[A], displayActualValue: Boolean): Validation[Option[A]] = {
        actual match {
          case Some(value) => {
            checkType match {
              case CheckType.contains => {
                if (s"${value}".contains(param)) {
                  actual.success
                } else {
                  s"${value}中未发现${param}".failure
                }
              }
              case CheckType.equals => {
                if (s"${value}".equals(param)) {
                  actual.success
                } else {
                  s"${value}与${param}不相等".failure
                }
              }
              case CheckType.startswith => {
                if (s"${value}".startsWith(param)) {
                  actual.success
                } else {
                  s"${value}不是以${param}开始".failure
                }
              }
              case CheckType.endswith => {
                if (s"${value}".endsWith(param)) {
                  actual.success
                } else {
                  s"${value}不是以${param}结尾".failure
                }
              }
              case _ => {
                "CheckType Error!".failure
              }
            }
          }
          case None => {
            "found nothing!".failure
          }
        }
      }
    }
    
    object CheckType {
      val contains: String = "contains"
      val equals: String = "equal"
      val startswith: String = "startwith"
      val endswith: String = "endwith"
    }
    
  • 相关阅读:
    2016-02-24 工作日记
    金字塔培训
    你找到自己的路了么?
    你是个成熟的职场人么?
    码农十年总结
    码农十年连载六
    码农十年连载五
    码农十年连载四
    码农十年连载三
    码农十年连载二
  • 原文地址:https://www.cnblogs.com/CSunShine/p/11911537.html
Copyright © 2020-2023  润新知