一、公共类抽取

熟悉Gatling的同学都知道Gatling脚本的同学都知道,Gatling的脚本包含三大部分:
  1. http head配置
  2. Scenario 执行细节
  3. setUp 组装
那么针对三部分我们需要在一套全流程测试当中把公共的部分提取出来写成Scala脚本公共类,来避免重复的工作和代码冗余:
在工程创建一个单独的目录如下图所示:

定义一个报头的基本格式:
package computerdatabase.JieOuData

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.http.config.HttpProtocolBuilder object phHttpProtocol {
implicit val noneWhiteList: io.gatling.core.filter.WhiteList = WhiteList ()
implicit
val noneBlackList: io.gatling.core.filter.BlackList = BlackList ()
implicit
val staticBlackList: io.gatling.core.filter.BlackList = BlackList (""".*\.js""", """.*\.css""", """.*\.gif""", """.*\.jpeg""", """.*\.jpg""", """.*\.ico""", """.*\.woff""", """.*\.(t|o)tf""", """.*\.png""")
implicit
val staticWhiteList: io.gatling.core.filter.WhiteList = WhiteList (""".*\.js""", """.*\.css""", """.*\.gif""", """.*\.jpeg""", """.*\.jpg""", """.*\.ico""", """.*\.woff""", """.*\.(t|o)tf""", """.*\.png""") def apply(host: String)(
implicit blackLst: io.gatling.core.filter.BlackList
, whiteLst: io.gatling.core.filter.WhiteList
): HttpProtocolBuilder = {
http.baseURL (host)
.inferHtmlResources (blackLst, whiteLst)
.acceptHeader ("application/json, text/javascript, */*; q=0.01")
.acceptEncodingHeader ("gzip, deflate")
.acceptLanguageHeader ("zh-CN,zh;q=0.9,zh-TW;q=0.8")
.doNotTrackHeader ("1")
.userAgentHeader ("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36")
}
}
定义报头的请求格式:
package computerdatabase.JieOuData

import io.gatling.http.config.HttpProtocolBuilder

object phHeaders {
val headers_base = Map ("Accept" -> "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "Upgrade-Insecure-Requests" -> "1")
}
定义一个home的接口:
package com.pharbers.gatling.scenario

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.core.structure.ChainBuilder
import com.pharbers.gatling.base.phHeaders.headers_base object getHome {
val getHome: ChainBuilder = exec (http ("home").get ("/").headers (headers_base))
}

  

定义login 接口:
package com.pharbers.gatling.scenario

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.core.structure.ChainBuilder
import com.pharbers.gatling.base.phHeaders.headers_json object userLogin {
val feeder = csv ("loginUser.csv").random println (feeder)
val login: ChainBuilder = exec (http ("login")
.get ("/api/user/login").headers (headers_json)
.body (StringBody ("""{ "condition" : { "email" : "nhwa", "password" : "nhwa" } }""")).asJSON)
}

  

一个完整的脚本:
package com.pharbers.gatling.simulation

import io.gatling.core.Predef._
import scala.concurrent.duration._
import com.pharbers.gatling.scenario._
import com.pharbers.gatling.base.phHttpProtocol
import com.pharbers.gatling.base.phHttpProtocol.{noneBlackList, noneWhiteList} class userLogin extends Simulation { val httpProtocol = phHttpProtocol ("http://192.168.100.141:9000")
val scn = scenario ("user_login")
.exec (getHome.getHome.pause (5 seconds), userLogin.login.pause (60 seconds)) setUp (scn.inject (rampUsers (1000) over (3 seconds))).protocols (httpProtocol)
}

  

  

这样看起来你的脚本是不是清爽很多

二、常用接口

 

并发量控制:
函数 解释
atOnceUsers(100) 使用100并发量测试目标服务器
rampUsers(100) over (10 seconds) 循序渐进的增大压力,在10s中内线性增加用户数达到最大压力100并发量
nothingFor(10 seconds) 等待10s
constantUsersPerSec(rate) during(duration) 在指定duration内,以固定频率注入用户,每秒注入rate个用户,默认固定间隔
constantUsersPerSec(rate) during(duration) randomized 与上面不同的是用户以随机间隔注入
rampUsersPerSec(rate1) to (rate2) during(duration) 在指定duration内,以递增频率注入用户,每秒注入 rate1 ~ rate2 个用户
用户行为控制:
函数 解释
exec()  实际的用户行为
pause(20) 用户滞留20s,模拟用户思考或者浏览内容
pause(min: Duration, max: Duration) 用户随机滞留,滞留时间在min ~ max 之间
流程控制:
函数 解释
repeat(time, counterName) 内置循环器
foreach(seq, elem, counterName)  foreach循环器
csv("file").random 创建填充器
doIf("", "") 判断语句
数据操作:

JDBC数据

jdbcFeeder("databaseUrl", "username", "password", "SELECT * FROM users")

Redis数据

import com.redis._import io.gatling.redis.Predef._

val redisPool = new RedisClientPool("localhost", 6379)

// use a list, so there's one single value per record, which is here named "foo"// same as redisFeeder(redisPool, "foo").LPOPval feeder = redisFeeder(redisPool, "foo")

// read data using SPOP command from a set named "foo"val feeder = redisFeeder(redisPool, "foo").SPOP

// read data using SRANDMEMBER command from a set named "foo"val feeder = redisFeeder(redisPool, "foo").SRANDMEMBER

文件数据

import java.io.{ File, PrintWriter }import io.gatling.redis.util.RedisHelper._

def generateOneMillionUrls(): Unit = {
val writer = new PrintWriter(new File("/tmp/loadtest.txt"))
try {
for (i <- 0 to 1000000) {
val url = "test?id=" + i
// note the list name "URLS" here
writer.write(generateRedisProtocol("LPUSH", "URLS", url))
}
} finally {
writer.close()
}}

迭代数据

import io.gatling.core.feeder._import java.util.concurrent.ThreadLocalRandom

// index records by projectval recordsByProject: Map[String, Seq[Record[Any]]] =
csv("projectIssue.csv").readRecords.groupBy { record => record("project").toString } // convert the Map values to get only the issues instead of the full recordsval issuesByProject: Map[String, Seq[Any]] =
recordsByProject.mapValues { records => records.map { record => record("issue") } } // inject projectfeed(csv("userProject.csv")) .exec { session =>
// fetch project from session
session("project").validate[String].map { project => // fetch project's issues
val issues = issuesByProject(project) // randomly select an issue
val selectedIssue = issues(ThreadLocalRandom.current.nextInt(issues.length)) // inject the issue in the session
session.set("issue", selectedIssue)
}
}

  

  

  

  

 

Gatling脚本编写技巧篇(一)的更多相关文章

  1. Gatling脚本编写技巧篇(二)

    脚本示例: import io.gatling.core.Predef._ import io.gatling.http.Predef._ import scala.concurrent.durati ...

  2. BAT脚本编写教程简单入门篇

    BAT脚本编写教程简单入门篇 批处理文件最常用的几个命令: echo表示显示此命令后的字符 echo on  表示在此语句后所有运行的命令都显示命令行本身 echo off 表示在此语句后所有运行的命 ...

  3. BAT脚本编写教程入门提高篇

    BAT脚本编写教程入门提高篇 批处理文件的参数 批处理文件还可以像C语言的函数一样使用参数(相当于DOS命令的命令行参数),这需要用到一个参数表示符“%”. %[1-9]表示参数,参数是指在运行批处理 ...

  4. X86逆向15:OD脚本的编写技巧

    本章节我们将学习OD脚本的使用与编写技巧,脚本有啥用呢?脚本的用处非常的大,比如我们要对按钮事件进行批量下断点,此时使用自动化脚本将大大减小我们的工作量,再比如有些比较简单的压缩壳需要脱壳,此时我们也 ...

  5. BAT脚本编写教程(比较易懂和全面)

    这篇文章主要介绍了BAT脚本编写教程,比较易懂和全面.适合有一定编程基础的人   作者不详.敬意! echo.@.call.pause.rem(小技巧:用::代替rem)是批处理文件最常用的几个命令, ...

  6. 《手把手教你》系列技巧篇(六)-java+ selenium自动化测试-阅读selenium源码(详细教程)

    1.简介 前面几篇基础系列文章,足够你迈进了Selenium门槛,再不济你也至少知道如何写你第一个基于Java的Selenium自动化测试脚本.接下来宏哥介绍Selenium技巧篇,主要是介绍一些常用 ...

  7. 《手把手教你》系列技巧篇(十五)-java+ selenium自动化测试-元素定位大法之By xpath中卷(详细教程)

    1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍定位倒数二个方法:By xpath.xpath 的定位方法, 非常强大.  使用这种方法几乎可以定位到页面上的任意元素. ...

  8. 《手把手教你》系列技巧篇(二十五)-java+ selenium自动化测试-FluentWait(详细教程)

    1.简介 其实今天介绍也讲解的也是一种等待的方法,有些童鞋或者小伙伴们会问宏哥,这也是一种等待方法,为什么不在上一篇文章中竹筒倒豆子一股脑的全部说完,反而又在这里单独写了一篇.那是因为这个比较重要,所 ...

  9. 《手把手教你》系列技巧篇(五十五)-java+ selenium自动化测试-上传文件-下篇(详细教程)

    1.简介 在实际工作中,我们进行web自动化的时候,文件上传是很常见的操作,例如上传用户头像,上传身份证信息等.所以宏哥打算按上传文件的分类对其进行一下讲解和分享. 2.为什么selenium没有提供 ...

随机推荐

  1. [源码分析] 从实例和源码入手看 Flink 之广播 Broadcast

    [源码分析] 从实例和源码入手看 Flink 之广播 Broadcast 0x00 摘要 本文将通过源码分析和实例讲解,带领大家熟悉Flink的广播变量机制. 0x01 业务需求 1. 场景需求 对黑 ...

  2. 【2019HDU多校】第九场1006/HDU6685-Rikka with Coin——位运算打表

    题目链接 题目大意 使用10.20.50.100元面额的硬币能分别组成题目给出的面额,需要最少的硬币个数 分析 一开始队友想用一堆if-else解决问题,然后WA了无数发-- 我想到了一种比较简单的打 ...

  3. ShedLock-jdbc配置锁

    项目初期为了快速响应业务开发,对于部分业务需要使用到定时任务功能模块,会直接嵌入到主流程代码中间.当业务增加,发展成分布式服务时,那些定时任务对整体而言重复执行.如果避免分布式服务中的定时任务单一执行 ...

  4. [SQL]CASE WHEN的用法及总结

    CASE WHEN的用法及总结 一.已知数据按照另外一种方式进行分组,分析 二.用一个SQL语句完成不同条件的分组 三.在Check中使用Case函数 四.根据条件有选择的UPDATE 五.两个表数据 ...

  5. Apache服务的主要目录和配置文件详解

    Apache服务的主要目录和配置文件详解 2014-01-14 19:05:14 标签:httpd配置文件详解 apache配置文件 httpd配置文件 apache文件目录 原创作品,允许转载,转载 ...

  6. OpenCV-Python 特征匹配 + 单应性查找对象 | 四十五

    目标 在本章节中,我们将把calib3d模块中的特征匹配和findHomography混合在一起,以在复杂图像中找到已知对象. 基础 那么我们在上一环节上做了什么?我们使用了queryImage,找到 ...

  7. FaceBook 发布星际争霸最大 AI 数据集

    简介 我们刚发布了最大的星际争霸:Brood War 重播数据集,有 65646 个游戏.完整的数据集经过压缩之后有 365 GB,1535 million 帧,和 496 million 操作动作. ...

  8. Excel决定吃什么

    1.Excel填充 在第一列填充1到100 (1)下拉填充 (2)填充——自动填充——序列 2.第二列加权填上自己吃的午饭 3.vloopup函数(列查找) 几乎都使用精确匹配,该项的参数一定要选择为 ...

  9. Python学习笔记:函数和变量详解

    一.面向对象:将客观世界的事物抽象成计算机中的数据结构 类:用class定义,这是当前编程的重点范式,以后会单独介绍. 二.函数编程:逻辑结构化和过程化的一种编程方法 1.函数-->用def定义 ...

  10. 使用 Visual Studio 开发、测试和部署 Azure Functions(一)开发

    1,什么是Azure functions Azure Functions 是 Microsoft Azure 提供的完全托管的 PaaS 服务,用于实现无服务器体系结构. Azure Function ...