Jmeter:JSR223脚本常见功能实现(JavaScript)

Json处理(JS)

对于Json字符串,需要使用单引号『''』(因为Json中已存在双引号)

// String转为Object
var jsonObj = JSON.parse('${data}');

// Object转为String
var jsonStr = JSON.stringify(jsonObj);

// 获取数组长度(直接通过length)
var len = obj.list.length;

获取当前Sample返回值,并转为Json

var response = prev.getResponseDataAsString();
var mData = JSON.parse(response);

缓存

存在一个默认勾选项:『如果可用,缓存编译脚本』,勾选后,不仅是脚本被缓存,其中的数据也会被缓存而不会更新(包括变量),如:

// 此处的${api}会编译为String,然后每次解析的都会是首次传入的变量
var jsonObj = JSON.parse('${api}');
vars.put("_id",jsonObj._id);

移除变量

vars.remove("data");

生成随机时间

通过组合使用Jmeter函数助手:__timeShift和__Random

# 使用:"${__timeShift(yyyy-MM-dd HH:mm:ss,,-PT${__Random(1,30000,)}H${__Random(1,300,)}M,,)}"

其中__timeShift的用法:
    "PT20.345S" -- parses as "20.345 seconds"
    "PT15M"     -- parses as "15 minutes" (where a minute is 60 seconds)
    "PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
    "P2D"       -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
    "P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
    "P-6H3M"    -- parses as "-6 hours and +3 minutes"
    "-P6H3M"    -- parses as "-6 hours and -3 minutes"
    "-P-6H+3M"  -- parses as "+6 hours and -3 minutes"

注意:使用H,M,S时,必须有T,T出现在H,M,S前,D后,如:P2DT3H4M。如没有D,则在P后,如:-PT6H3M。参考:https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-

数组取随机index

var temp = ["1","2","3","4","5"];
temp[Math.floor((Math.random()*temp.length))];

判断字符串是否包含(JS)

"${__V(title,)}".indexOf("测试") != -1

当变量不存在时,才设置变量(JS)

// 一般只适用于host及登录,否则有坑:如果在后续使用中需要修改该参数,则该方法无效
function setDefaultVar(varName,value){
	if (vars.get(varName) == null) {
		log.info("--------------- "+varName+" is not set, use: "+ value +" ---------------")
		vars.put(varName, value);
	}
}

获取任意范围内随机整数

// 随机获取范围内的整数
function random(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
};

从数组中随机选择一个

// 从数组中,随机选择一个
function randomChooice(array){
	return array[Math.floor(Math.random() * array.length)];
}

从对象中随机选择key(typescript代码,需转为JS才能在Jmeter使用)

private randomKeyInObject(obj: { [k: string]: string }) {
        let keys = Object.keys(obj)
        let randomIndex = Math.floor(Math.random() * keys.length);
        return keys[randomIndex];
    }

把数组设置为X个单独变量

// 把数组设置为X个单独变量
function arrayToVars(prefixKey, array) {
    for (var index = 0; index < array.length; index++) {
        var key = prefixKey + "_" + (index + 1);
        vars.put(key, array[index]);
    }
}

使用自己的『四舍五入』方法

// 修改toFixe,在Jmeter中非常不友好所以使用自己的方法
function toFixed(num, len) {
    if (len === void 0) { len = 2;}
    // Jmeter中不能使用:Number.EPSILON(ES6才出来)
    return Math.round((Number(num) + 2.2204460492503130808472633361816E-16) * Math.pow(10, len)) / Math.pow(10, len);
}

AssertionResult封装

// 断言是否相等(数字与字符类型分别处理)
function assertEqual(expect, actual, errorMsg) {
    var numberReg=/^-?[0-9]+.?[0-9]*$/;
    if(numberReg.test(expect) && numberReg.test(actual)){
        if (Number(expect) != Number(actual)) {
            AssertionResult.setResultForFailure(errorMsg + ":" + " ,expect: " + expect + " , but got: " + actual);
        }
    }else {
        if (expect != actual) {
            AssertionResult.setResultForFailure(errorMsg + ":" + " ,expect: " + expect + " , but got: " + actual);
        }
    } 
}

获取默认变量

// 获取变量,如没有,则返回:defaultValue
function getVarWithDefault(varName,defaultValue){
	var theVar = vars.get(varName);
	if(theVar == null){
		theVar = defaultValue;
	}
	return theVar;
}

Loop循环中获取子变量

// Loop循环中获取子变量,需配合计数器使用,loopFlag为计数器的引用名称,默认为index
function getSubVarInLoop(prefix, loopFlag) {
    if (loopFlag === void 0) loopFlag = "index";
    var key = prefix + "_" + vars.get(loopFlag);
    return vars.get(key);
}

解决JavaScript浮点数相加出现多位小数的Bug

// 解决JavaScript浮点数相加出现多位小数的Bug
function toDecimal(x) {
    var val = Number(x)
    if (!isNaN(parseFloat(val))) {
        val = val.toFixed(2);
    }
    return val;
}

修改toFixed为『四舍五入』,而不是『四舍六入五留双』

Number.prototype.toFixed = function (len) {
    if (len > 20 || len < 0) {
        throw new RangeError('toFixed() digits argument must be between 0 and 20');
    }
    // .123转为0.123
    var number = Number(this);
    if (isNaN(number) || number >= Math.pow(10, 21)) {
        return number.toString();
    }
    if (typeof (len) == 'undefined' || len == 0) {
        return (Math.round(number)).toString();
    }
    var result = number.toString(),
        numberArr = result.split('.');

    if (numberArr.length < 2) {
        //整数的情况
        return padNum(result);
    }
    var intNum = numberArr[0], //整数部分
        deciNum = numberArr[1],//小数部分
        lastNum = deciNum.substr(len, 1);//最后一个数字

    if (deciNum.length == len) {
        //需要截取的长度等于当前长度
        return result;
    }
    if (deciNum.length < len) {
        //需要截取的长度大于当前长度 1.3.toFixed(2)
        return padNum(result)
    }
    //需要截取的长度小于当前长度,需要判断最后一位数字
    result = intNum + '.' + deciNum.substr(0, len);
    if (parseInt(lastNum, 10) >= 5) {
        //最后一位数字大于5,要进位
        var times = Math.pow(10, len); //需要放大的倍数
        var changedInt = Number(result.replace('.', ''));//截取后转为整数
        var fu = 1/changedInt < 0;// 为true 时,则 changedInt < 0 或者 changedInt = -0,否则为正数或等于0
        if(fu){
            changedInt--;//整数进位
        }else{
            changedInt++;//整数进位
        }
        changedInt /= times;//整数转为小数,注:有可能还是整数
        result = padNum(changedInt + '');
    }
    return result;
    //对数字末尾加0
    function padNum(num) {
        var dotPos = num.indexOf('.');
        if (dotPos === -1) {
            //整数的情况
            num += '.';
            for (var i = 0; i < len; i++) {
                num += '0';
            }
            return num;
        } else {
            //小数的情况
            var need = len - (num.length - dotPos - 1);
            for (var j = 0; j < need; j++) {
                num += '0';
            }
            return num;
        }
    }
};

在string中去除某string

# 在toBeDelete(string)中去除deleteWhat(string)
function deleteString(toBeDelete, deleteWhat, splitChar) {
  var toBeDelete = toBeDelete.split(",");
  var deleteWhat = deleteWhat.split(",");
  for (var i = 0; i < toBeDelete.length; i++) {
    for (var j = 0; j < deleteWhat.length; j++) {
      if (deleteWhat[j] === toBeDelete[i]) {
        var temp = toBeDelete.splice(i--, 1);
        log.info("delete string: " + temp);
      }
    }
  }
  return toBeDelete.join(splitChar);
}

var result = deleteString("1,42,12,33,6,642,118", "42,36,118,62,27,12,53", ",");
console.log(result);

生成范围内的随机日期

// 范围内的随机日期,不带时分秒
function randomDate(startDate,EndDate){
    var st = startDate.split('-');
    var et = EndDate.split('-');
    var startTime = new Date(st[0], st[1] - 1, st[2]).getTime();
    var endTime = new Date(et[0], et[1] - 1, et[2]).getTime();
    var formatTime = function(time, spliter = '-') {
        var date = new Date(time);
        var year = date.getFullYear();
        var month = (date.getMonth() + 1) >= 10 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1);
        var day = date.getDate() >= 10 ? date.getDate() : '0' + date.getDate();
        return `${year}${spliter}${month}${spliter}${day}`
    }
    var random = function(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    };
    i = random(startTime,endTime);
    var result = formatTime(i, '')
    return result;
}
posted @ 2020-10-14 19:16  Feng1024  阅读(1810)  评论(0编辑  收藏  举报