Ngrinder脚本开发各细节锦集(groovy)

Stella981
• 阅读 651
1、生成随机字符串(import org.apache.commons.lang.RandomStringUtils)
        数字:RandomStringUtils.randomNumeric(length);
        字母:RandomStringUtils.randomAlphabetic(length);
        字母加数字:RandomStringUtils.randomAlphanumeric(length);
        所有ASCCII字符:RandomStringUtils.randomAscii(length);
        自定义混合字符:RandomStringUtils.randomAscii(length, string);
    
2、生成随机数字:(import java.util.concurrent.ThreadLocalRandom;)
        数字:int random_number = ThreadLocalRandom.current().nextInt(min_num, max_num);
    
3、获取项目数据文件路径
        common项目:"/resources/account.txt"
        maven项目:Thread.currentThread().getContextClassLoader().getResource("/account.txt").getPath();
        maven项目获取文件内容:ReflectionUtils.getCallingClass(0).getResourceAsStream("/account.txt").getText("UTF-8")
4、读取文件:
        txt每行单数据:    String[] file_arrary = new File("/resources/account.txt") as String[]; 
                        String file_data = file_arrary[arrary_index];
                                    
        txt每行双数据:    String[] file_arrary = new File("/resources/account.txt") as String[]; 
                        String data_one = file_arrary[arrary_index].split(",")[0];
                        String data_two = file_arrary[arrary_index].split(",")[1];
        另一种方法:        
                        List<String> reqDataArrList = new File(dataFilePath).readLines()
                        String data_one = reqDataArrList.get(arrary_index).split(",")[0];
                        String data_two = reqDataArrList.get(arrary_index).split(",")[1];
                        
        txt每行多数据可参考双数据方法。也可以参考json方式存储:
                                    BufferedReader txt_content=new BufferedReader(new FileReader(new File("/resources/account.txt")))
                                    data_json = new JSONObject()
                                    String text_line = ""
                                    while(( text_line=txt_content.readLine())!=null){
                                        data_json.put(text_line.split(",")[0],text_line.split(",")[1])
                                    }
                                    String data_one = data_json.keys[0]
                                    String data_two = data_json.getString(data_one)
5、写入文件:
        覆盖写入:    def write = new File(file_path, file_name).newPrintWriter();
                            write.write(write_text);
                            write.flush();
                            write.close()
                            
        追加写入:    def write = new File(file_path, file_name).newPrintWriter();
                            write.append(write_text);
                            write.flush();
                            write.close()
                            
6、json文件的数据处理(import org.ngrinder.recorder.RecorderUtils)
        json文件读取:    String json_str = new File(file_path).getText("UTF-8")
                                    def json_object = RecorderUtils.parseRequestToJson(json_str)
                                    
                                    长度:json_object.length()
                                    关键字:json_object.keys()
                                    添加元素:json_object.put(name, value)
                                    修改元素:json_object.put(name, value)
                                    删除元素:json_object.remove(name, value)
                                    获取对应value:json_object.getString(name)
                                    
7、字符串的处理
        字符串截取:String new_str = old_str[0..3]
        字符串替换:String string = str.replace("old","new")
        字符串统计:int count = string.count("char")
        字符串转化:int int_num = Integer.parseInt(string)
    
1、设置多个请求事务(即多个test方法)
        1)设置多个静态Gtest对象:
            public static GTest test1
            public static GTest test2
        2)实例化多个Gtest对象:
            test1 = new GTest(1, "test1");
            test2 = new GTest(2, "test2");
        3)监听多个test请求:
            test1.record(this, "test1")
            test2.record(this, "test2")
        4)定义多个test方法:
            public void test1(){
                grinder.logger.info("---ones: {}---", grinder.threadNumber+1)
            }
            public void test2(){
                grinder.logger.info("---twos: {}---", grinder.threadNumber+1)
            }
        
2、Ngrinder定义请求参数集:
        add方法:    List<NVPair> paramList = new ArrayList<NVPair>();
                            paramList.add(new NVPair("name", "value"));
                            paramList.add(new NVPair("name", "value"));
                            params = paramList.toArray();
                            
        new方法:    params = [new NVPair("name", "value"), new NVPair("name", "value")];
                                    
3、Ngrinder处理日志:
        日志级别(三种常见):    grinder.logger.info("----before process.----");
                                                grinder.logger.warn("----before process.----");
                                                grinder.logger.error("----before process.----");
                                                
        日志限定(仅打印error级别) :
                                    1)导入依赖包
                                    import ch.qos.logback.classic.Level;
                                    import org.slf4j.LoggerFactory;
                                    2)设定级别
                                    @BeforeThread
                                        LoggerFactory.getLogger("worker").setLevel(Level.ERROR);
                                    3)设置打印语句
                                    @test
                                        grinder.logger.error("----error.----");
        日志输出(输出所有进程日志):将每个agent的.ngrinder_agent/agent.conf中一项修改为agent.all_logs=true
        
        日志打印:打印变量:grinder.logger.error("{},{}",variable1,variable2); // 换行或缩进可在""中加\n或\t
        
4、Ngrinder的cookie处理
        1) 登录产生cookie
            @BeforeThread 
                login_get_cookie(); // 调用登录方法
                cookies = CookieModule.listAllCookies(HTTPPluginControl.getThreadHTTPClientContext()); // 配置cookie管理器
        2) 读取控制器中cookie
            @Before
                cookies.each { CookieModule.addCookie(it, HTTPPluginControl.getThreadHTTPClientContext()) }
    
5、Ngrinder请求方式:
        1)通过url加参数直接访问:
            post方法:    HTTPResponse result = request.POST("http://192.168.2.135:8080/blogs", params, headers)
            get方法:    HTTPResponse result = request.GET("http://192.168.2.135:8080/blogs", params, headers)
            参数是json:设置请求头参数{"Content-Type": "application/json"}
        2)通过参数化所有请求数据为json对象(导入import org.ngrinder.recorder.RecorderUtils)
                            HTTPResponse result = RecorderUtils.sendBy(request, req_data_json)
                            HTTPResponse result = RecorderUtils.sendBy(request, req_data_json)
                            
6、Ngringer的test运行次数设定(将总运行测试次数按百分比例分配到相应test):
        1)引用依赖包:
            import net.grinder.scriptengine.groovy.junit.annotation.RunRate
        2)设置运行次数百分比(所有test设定的比例值不够100,那不满的部分不运行,比如设定总比80,只运行这80部分):
            @RunRate(50)  // 数字代表百分比
            @Test
            public void test1(){}
            @RunRate(50)  // 数字代表百分比
            @Test
            public void test2(){}
            
7、Ngringer获取设置的加压机总数、进程总数、线程总数等信息:
        int tota_agents = Integer.parseInt(grinder.getProperties().get("grinder.agents").toString()) // 设置的总加压机数
        int total_processes = Integer.parseInt(grinder.properties().get("grinder.processes").toString()) // 设置的总进程数
        int total_threads = Integer.parseInt(grinder.properties().get("grinder.threads").toString()) // 设置的总线程数
        int total_runs = Integer.parseInt(grinder.properties().get("grinder.runs").toString()) // 设置的总运行次数(若设置的是运行时长,则得到0)
                                            
8、Ngringer获取当前运行的加压机编号、进程编号、线程编号等信息(都从0递增):
        int agent_number = grinder.agentNumber // 当前运行的加压机编号
        int process_number = grinder.processNumber // 当前运行的进程编号
        int thread_number = grinder.threadNumber // 当前运行的线程编号
        int run_number = grinder.runNumber // 当前运行的运行次数编号
        
9、Ngringer获取唯一递增值方法(从1递增,不重复):
        // 传递接口参数runNumber(即def runNumber = grinder.runNumber)
        private int getIncrementId(int runNumber){
            // 获取压力机总数、进程总数、线程总数
            int totalAgents = Integer.parseInt(grinder.getProperties().get("grinder.agents").toString())
            int totalProcess = Integer.parseInt(grinder.getProperties().get("grinder.processes").toString())
            int totalThreads = Integer.parseInt(grinder.getProperties().get("grinder.threads").toString())
            
            // 获取当前压力机数、进程数、线程数
            int agentNum = grinder.agentNumber
            int processNum = grinder.processNumber
            int threadNum = grinder.threadNumber
            
            // 获取唯一递增数id
            int incrementId = agentNum * totalProcess * totalThreads + processNum * totalThreads + threadNum + totalAgents * totalProcess * totalThreads * runNumber
            return incrementId
        }

10、Ngringer根据唯一递增值获取参数化文件中的唯一行号:
        1)需要设置静态变量:private enum WhenOutOfValues { AbortVuser, ContinueInCycleManner, ContinueWithLastValue }
        2)传递接口参数fileDataList(即def fileDataList = new File(dataFilePath).readLines())
        private int getLineNum(def fileDataList) {
            // 获取当前运行数、数据读取行数、数据最大行数
            int counter = getIncrementId(grinder.runNumber)
            int lineNum = counter + 1
            int maxLineNum = fileDataList.size() - 1
            
            // 读取最大值的判断处理
            WhenOutOfValues outHandler = WhenOutOfValues.AbortVuser
            if (lineNum > maxLineNum) {
                 if(outHandler.equals(WhenOutOfValues.AbortVuser)) {
                    lineNum = maxLineNum //grinder.stopThisWorkerThread()
                 } else if (outHandler.equals(WhenOutOfValues.ContinueInCycleManner)) {
                    lineNum = (lineNum - 1) % maxLineNum + 1
                 } else if (outHandler.equals(WhenOutOfValues.ContinueWithLastValue)) {
                     lineNum = maxLineNum
                 }
            }
            return lineNum
        }
11、Ngrinder日志输出配置的测试信息:(import java.text.SimpleDateFormat)
        public static String getTestInfo(){
            String time_string = ""
            // 获取压测时设置的进程总数、线程总数、运行次数并在log中打印
            int all_process = grinder.getProperties().getInt("grinder.processes", 1) // 设置的总进程数
            int all_threads = grinder.getProperties().getInt("grinder.threads", 1)  // 设置的总线程数
            int all_runs = grinder.getProperties().getInt("grinder.runs", 1)  // 设置的总运行次数(若设置的是运行时长,则得到0)
            int all_duration = grinder.getProperties().getLong("grinder.duration", 1) // 设置的总运行时长(若设置的是运行次数,则得到0)
            // 格式化时间毫秒输出(输出格式00:00:00)
            SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss")
            formatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"))
            String all_duration_str = formatter.format(all_duration)
            if (all_duration_str.equals("00:00:00"))
                time_string = "Test information: the processes is "+all_process+", the threads is "+all_threads+", the run count is "+all_runs+"."
            else
                time_string = "Test information: the processes is "+all_process+", the threads is "+all_threads+", the run time is "+all_duration_str+"."
            return time_string
        }
12、Ngrinder打印所有的配置信息
            String property = grinder.getProperties();
            grinder.logger.info("------- {}", property) ;

13、Ngrinder获取请求返回值:
            HTTPResponse result = request.POST("http://192.168.2.135:8080/blogs", params, headers)
            返回的文本:grinder.logger.info("----{}----", result.getText()) // 或者result.text
            返回的状态码:grinder.logger.info("----{}----", result.getStatusCode()) // 或者result.statusCode
            返回的url:grinder.logger.info("----{}----", result.getEffectiveURI())
            返回的请求头所有参数:grinder.logger.info("---\n{}---", result)
            返回的请求头某参数:grinder.logger.info("----{}---- ", result.getHeader("Content-type"))
            
14、Ngrinder返回值的匹配:
    匹配状态码:assertThat(result.getStatusCode(), is(200))
    匹配包含文本:assertThat(result.getText(), containsString("success"))
            
15、Ngrinder获取所有虚拟用户数:
    public int getVusers() {
        int totalAgents = Integer.parseInt(grinder.getProperties().get("grinder.agents").toString());
        int totalProcesses = Integer.parseInt(grinder.getProperties().get("grinder.processes").toString());
        int totalThreads = Integer.parseInt(grinder.getProperties().get("grinder.threads").toString());
        int vusers = totalAgents * totalProcesses * totalThreads;
        return vusers;
    }
16、Ngrinder的断言和error日志输出
    if (result.statusCode == 301 || result.statusCode == 302) {
            grinder.logger.error("Possible error: {} expected: <200> but was: <{}>.",result.getEffectiveURI(),result.statusCode); 
        } else {
            assertEquals((String)result.getEffectiveURI(), result.statusCode, 200)
            assertThat((String)result.getEffectiveURI(), result.statusCode, is(200))
        }

 参考文档:

  1、https://testerhome.com/topics/17585?locale=zh-CN

  2、https://my.oschina.net/aub/blog/858483

  3、https://blog.csdn.net/u013512987/article/details/81776845

  4、https://www.cnblogs.com/zjsupermanblog/archive/2017/08/18/7390980.html

  5、https://www.cnblogs.com/lindows/p/10517839.html

  6、https://www.cnblogs.com/zhongyehai/p/10386478.html

点赞
收藏
评论区
推荐文章
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java判断字符串是否为数字或中文或字母
1.判断字符串是否仅为数字:1用JAVA自带的函数public static boolean isNumeric(String str){  for (int i  str.length();i0;){      if (!Character.isDigit(str.charAt(i))){
Stella981 Stella981
3年前
Python批量生成用户名
写在最前平时在工作中尤其是在做压测的时候难免需要一些用户名和密码,写个简单的Python小脚本批量生成一些代码示例1importrandom,string23生成大小字母和数字一起的大字符串4all_strstring.ascii_lettersstring.digit
Wesley13 Wesley13
3年前
C语言概述
C语言基本语法单位字符集字符是高级语言中的最小单位,是构成语法单位的基础。C语言中规定可以使用的合法字符的集合为C字符集C字符集采用ASCII码字符集C语言字符集由下列字符组成(1)字母和数字字符。(小写字母a~z、大写字母A~Z、数字0~9)(2)不可打印的字符。(空格符、回车符、换行符、控
Wesley13 Wesley13
3年前
MySQL 数据类型
在MySQL中,有三种主要的类型:文本、数字和日期/时间类型。Text类型:数据类型描述备注CHAR(size)保存固定长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的长度。最多255个字符。VARCHAR(size)保存可变长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串
Stella981 Stella981
3年前
AJPFX总结关于Java中过滤出字母、数字和中文的正则表达式
1、Java中过滤出字母、数字和中文的正则表达式(1)过滤出字母的正则表达式\^(AZaz)\(2)过滤出数字的正则表达式\^(09)\(3)过滤出中文的正则表达式\^(\\\\u4e00\\\\u9fa5)\(4)过滤出字母、数字和中文的正则表达式\^(azAZ09\\\\u
Wesley13 Wesley13
3年前
PHP 生成随机字符串
/生成随机字符串@author宁佳兵<meilijing.ning@foxmail.com@paramint$length@returnstring/functioncreateNonceStr($length16){$
Stella981 Stella981
3年前
PHP利用32进制生成固定长度字符串对id加密解密
我们在实际项目运用中,难免会要求对ID进行加密,生成特定的字符串,比如生成用户邀请码,这样不用查数据库也可以反向解密到id为什么使用32进制因为数字加字母长度为36位,32位生成后不用区别用户输入不用区分大小写<?phpclassIDAES{$baseChar'0123456789
马尚 马尚
6个月前
用Python和机器学习识别英文数字验证码
在本项目中,我们将展示如何使用Python和机器学习技术来识别英文数字验证码。英文数字验证码通常包含了一系列随机生成的字母和数字,我们将利用机器学习模型来训练识别这些验证码。首先,我们需要导入所需的库:pythonimportosimportnumpyas
马尚 马尚
6个月前
使用OpenCV和Tesseract识别英文数字验证码
在这个项目中,我们将展示如何使用OpenCV和Tesseract来识别英文数字验证码。验证码是一种常见的安全措施,用于防止机器人或恶意软件的访问。英文数字验证码通常包含了随机生成的字母和数字,我们将利用OpenCV进行图像处理,并使用Tesseract来进