一、Postman工具
1.Base64加解密
Base64加密:
//base64加密
var username=CryptoJS.enc.Utf8.parse("admin");//先转为UTF-8格式
var base64_username=CryptoJS.enc.Base64.stringify(username);//进行Base64加密
console.log(base64_username);
Base64解密:
//base64解密
var username = CryptoJS.enc.Base64.parse("YWRtaW4=");//进行解密
var utf8_username = username.toString(CryptoJS.enc.Utf8);//转为UTF-8格式
console.log(utf8_username);
2.MD5加密
//MD5加密(转换为MD5加密(32位小写),再转为字符串,并将转码后的字符串转换为32位大写)
var MD5_username = CryptoJS.MD5("admin").toString().toUpperCase();
console.log(MD5_username);
3.RSA加密解密
请求参数:
{
"code":"574526",
"phone":"{{aes$17803878944}}",
"cardId":"{{rsa$410922199008151440}}"
}
Pre-request Script脚本
// ------ 导入RSA ------
if(!pm.globals.has("forgeJS")){
pm.sendRequest("https://raw.githubusercontent.com/loveiset/RSAForPostman/master/forge.js", (err, res) => {
if (!err) {
pm.globals.set("forgeJS", res.text())
}
})}
eval(postman.getGlobalVariable("forgeJS"));
// ------------ AES 加密 ------------
function aesEncrypt(content){
//console.log('AES: ' + content);
//密钥
const key = CryptoJS.enc.Utf8.parse("Y5MUIOM7BUWI7BQR");
//盐
const iv = CryptoJS.enc.Utf8.parse('S41AXIPFRFVJL73Z');
const encrypted = CryptoJS.AES.encrypt(content, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7});
return encrypted.toString();
}
//设置公钥变量
var RSA_Public_Key = "-----BEGIN PUBLIC KEY-----\n" +
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtamh2rXIlzOxWCdFeVzs\n" +
"+7yDlZnd+UmbsJ1JtGQ6tSxY0YgLzilWKSbCpyOXBDeU77WfgGOUW0XKAPZ+vI9e\n" +
"cvJrPWWEsaVM4liVrgpzOUeDeZYpPiYagUM2nsQ5iJ9lSGLdjIza1HC9xP0u3Soc\n" +
"MK3d2rImYfZAVwBeUSew11hwXc4tQWaig1RI2Wjzak6ED0kW3Cvew/C/q1zTiRvo\n" +
"8wH1OXDJ8kqGJylIRxKiFd2LaWerNtpQ4lGXZ+P8E3xkdIfpiNKOPbIosO1laf7d\n" +
"5xmSrvbteZ8Y1A6aqs6QwhkiSVmKTJNgIFoPboPRuAD3Vkm4CniMmoKULm6YBsn+\n" +
"VwIDAQAB\n" +
"-----END PUBLIC KEY-----";
pm.collectionVariables.set("RSA_Public_Key", RSA_Public_Key);
// ------------ RSA 加密 ------------
function rsaEncrypt(content){
const pubKey = pm.collectionVariables.get("RSA_Public_Key");
if(pubKey){
const publicKey = forge.pki.publicKeyFromPem(pubKey);
const encryptedText = forge.util.encode64(
publicKey.encrypt(content, 'RSAES-PKCS1-V1_5', {
md: forge.md.sha1.create(),
mgf: forge.mgf.mgf1.create(forge.md.sha1.create())
}));
return encryptedText;
}
}
//对请求数据开始加密
function getBracketStr(text) {
let result = ''
let regex = /{{(.+?)}}/g;
let options = text.match(regex);
if (options && options.length > 0) {
let option = options[0];
if (option) {
result = option.substring(2, option.length - 2)
}
}
return result
}
// ------ 存储所有未加密环境变量 ------
if(!pm.environment.has('localStore')){
pm.environment.set('localStore', '{}');
}
let localStore = JSON.parse(pm.environment.get('localStore'));
// 获取当前请求中的加密变量
let requestData;
if((typeof request.data) === 'string'){
requestData = JSON.parse(request.data)
} else {
requestData = request.data;
}
requestData = Object.assign(requestData, request.headers);
Object.keys(requestData).map(key => {
let value = requestData[key] + ''; // 内容
if (value.indexOf('{{') !== -1) { // 是否为变量
let content = getBracketStr(value);
// 判断是否加密
if (content.indexOf('aes$') !== -1) {
let c = content.split('aes$')[1];
let encryptedContent = pm.environment.get(c); // 加密内容
encryptedContent = encryptedContent ? encryptedContent : c;
pm.environment.set(content, aesEncrypt(encryptedContent));
localStore[content] = aesEncrypt(encryptedContent);
} else if (content.indexOf('rsa$') !== -1) {
let c = content.split('rsa$')[1];
let encryptedContent = pm.environment.get(c); // 加密内容
encryptedContent = encryptedContent ? encryptedContent : c;
pm.environment.set(content, rsaEncrypt(encryptedContent));
localStore[content] = rsaEncrypt(encryptedContent);
}
}
});
pm.environment.set('localStore', JSON.stringify(localStore));
console.log(JSON.stringify(localStore))
服务端处理:
AES aes = new AES("CBC", "PKCS7Padding",
// 密钥,可以自定义
"Y5MUIOM7BUWI7BQR".getBytes(),
// iv加盐,按照实际需求添加
"S41AXIPFRFVJL73Z".getBytes());
log.info("phone解密前:【{}】", loginForm.getPhone());
byte[] decryptPhone = aes.decrypt(loginForm.getPhone());
log.info("phone解密后:【{}】", new String(decryptPhone));
log.info("cardId解密前:【{}】", loginForm.getCardId());
RSA rsa = new RSA(RSAEncryptConfig.PRIVATEKEY, null);
byte[] cardId = rsa.decrypt(loginForm.getCardId(), KeyType.PrivateKey);
log.info("cardId解密后:【{}】", new String(cardId));
4.接口关联
//获取返回的json数据
var jsonData = pm.response.json();
var token = jsonData.token;
pm.collectionVariables.set("token", token);
5.断言
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
pm.test("Your test name", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.value).to.eql(100);
});
6.解析请求数据和响应数据
//解析请求数据
var requestData = JSON.parse(request.data);
//解析响应数据
var responseData = JSON.parse(responseBody);
7.设置时间戳
//设置当前时间戳毫秒
postman.setGlobalVariable("timestamp",Math.round(new Date().getTime()));
8.加签和验签
加签
//获取请求数据
var data = JSON.parse(request.data)
//请求时间戳
var reqTime = Math.round(new Date().getTime());
pm.collectionVariables.set("reqTime",reqTime);
data.reqTime = reqTime;
//连接符
var join = '&';
var result = '';
//键按首字母排序
let keys = Object.keys(data).sort();
for(var i = 0; i < keys.length; i++){
let key = keys[i];
let value = data[key] + '';
if(value.indexOf('{{') !== -1) continue;
result = result + key + '=' + value + join;
}
//拼接支付宝沙箱应用公钥
result = result + "key=MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7o5JU5TxREr7Clea+aJSgpnF+vV12bLF9xngRZpHewZXNQJ5mTevPJloMcLZzwjKgisAib0hqQDc8pNW05d3x0u84aBQa/FK/C/xvfc+4krDFE6M/kHTZTW+RGX0bNDiXePVeb71Of6GEiiWvTG+j7nnjqVoRjL/+TX5ut8bkOgYIirhh+4VWndGjQQpHlK05m/fQckAS6qbk8/yZVeHswygfP/qqVc6BB2lDZVM3SBBx5DhPQjg1trUJQqA/AXtQmsKcVsSzTLyDRfenpt1NuGGSI+Ba1zwijB9m+Tuzdpv+rVet87bxcbbu1neEHuhzFWPLB1ZReezwfuGpgpKXAgMBAAECggEAUjpsdie/Nwgv8LYgWHEcMQq/0frKaotXfPbsxzNb2XKcY0ZeJBchr7Xu4GTEkBYaeaBUcsKxyV461qilvpC9oqv9iYqSxQCugmqORY2s6gXe0X65m7GCg3gb3Ep/ONy5sCeh37C4FR55ecvQl/G3Ou/XGp2siuRTfu4W6g4/auQCVAm1zefMhVEuIZLukIHLrxzAKF92X8RHNOWY/fvYI7dZiDX+CnWQdVdeuvdeJCi7ZR4bl89gVpM2bpNhVXwnrHI/szcyIDuk9CdNhDSjc5YqT6stkOnS+/3wMURb8X5F0WVO1rqkcB7WmbqdpYH4vnI0OitwVVW0QcOFn8qlgQKBgQDliQofNRnoezzsr8/JWW0H658Q5NQUAn0FeBTtnMTDczOYRcZ4EeFjEB4WEtXXBRSZG+tSNcEU3JiPOWCD8zKzhzFnboLIT8xfT0wZHqwMvvTPQ4aSqllf21MfxAC+l6dNMAv/lPirI6KU+w1zukqMVRXWeYzMOaPru1uUa01GdQKBgQDRRet5cjcXP81lbPGb4+IU93xozNDQFQop1ExSsspBIpFwwzr80MHDn+fcy6zIiWwW8el9XW+F/Ktd2FpWsM3OssoV9dw1zDQEWoQxuLzZnKejFYSnt2oAc5GZPmJWHyQ+RDD1cORFLucs24d8ukmblCGdLmXEIcPzBZOegYWLWwKBgQCQf2HQ3ZPux85FzjQHtHUv/EPJ1dQwuJRN4heCsiMoS5iabqqPoen6fAYErVzTHM6nyGyu90oSwQCFgYBh8LLlU+FlFKveQGYPRhNI6Qc0iu4AoKjSIc1by+2bXL9/PGdE709OWVDmI+vQz+7bANa3W0UBHMnnMw4fc3YmjBo8lQKBgQCyP3jS55rO/bQoGMQuQMrXivj3lsShB9qxSDd+FPU6x4PT5SZAIlt4EaJ/KShRYuOjI4f6FPShzlX0SAyiXFPgI98HF3PqirUfpC2G4FBSliEfQnvMEuiB2+3+9ejya/IF6zU8SVzVJJ8ZUR80+MMrdd+vrs5VYWEyhOR4lN+3kwKBgB471kJOZC9YMWfaXSyKSahnlBHQyuTzJZRaKUqrMquKFrbyXcEoevwCmVk5t1I+1nZ7gm1mXmhfmdIYPnOBBKD2pSrIn8aGGJmBp012yQEuIXiDQBLOjJKOjScvG8xJlm6waW7K+7BG51FkWKWcbDkq+BJ54xcZmIls/ILNWS8T";
console.log(result)
pm.collectionVariables.unset("sign");
var sign = CryptoJS.MD5(result).toString().toUpperCase();
console.log(sign)
pm.collectionVariables.set("sign", sign);
验签
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
pm.test("检验业务响应码是否正常", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.code).to.eql(0);
});
//验签
pm.test("验签", function () {
//获取响应内容
var jsonData = pm.response.json();
var data = jsonData.data;
//字段按首字母排序
let keys = Object.keys(data).sort();
var result = '';
var join = '&'; //连接符号
for(var i = 0; i < keys.length; i++){
let key = keys[i];
result = result + key + '=' + data[key] + join;
}
//拼接支付宝沙箱应用公钥
result = result + "key=MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7o5JU5TxREr7Clea+aJSgpnF+vV12bLF9xngRZpHewZXNQJ5mTevPJloMcLZzwjKgisAib0hqQDc8pNW05d3x0u84aBQa/FK/C/xvfc+4krDFE6M/kHTZTW+RGX0bNDiXePVeb71Of6GEiiWvTG+j7nnjqVoRjL/+TX5ut8bkOgYIirhh+4VWndGjQQpHlK05m/fQckAS6qbk8/yZVeHswygfP/qqVc6BB2lDZVM3SBBx5DhPQjg1trUJQqA/AXtQmsKcVsSzTLyDRfenpt1NuGGSI+Ba1zwijB9m+Tuzdpv+rVet87bxcbbu1neEHuhzFWPLB1ZReezwfuGpgpKXAgMBAAECggEAUjpsdie/Nwgv8LYgWHEcMQq/0frKaotXfPbsxzNb2XKcY0ZeJBchr7Xu4GTEkBYaeaBUcsKxyV461qilvpC9oqv9iYqSxQCugmqORY2s6gXe0X65m7GCg3gb3Ep/ONy5sCeh37C4FR55ecvQl/G3Ou/XGp2siuRTfu4W6g4/auQCVAm1zefMhVEuIZLukIHLrxzAKF92X8RHNOWY/fvYI7dZiDX+CnWQdVdeuvdeJCi7ZR4bl89gVpM2bpNhVXwnrHI/szcyIDuk9CdNhDSjc5YqT6stkOnS+/3wMURb8X5F0WVO1rqkcB7WmbqdpYH4vnI0OitwVVW0QcOFn8qlgQKBgQDliQofNRnoezzsr8/JWW0H658Q5NQUAn0FeBTtnMTDczOYRcZ4EeFjEB4WEtXXBRSZG+tSNcEU3JiPOWCD8zKzhzFnboLIT8xfT0wZHqwMvvTPQ4aSqllf21MfxAC+l6dNMAv/lPirI6KU+w1zukqMVRXWeYzMOaPru1uUa01GdQKBgQDRRet5cjcXP81lbPGb4+IU93xozNDQFQop1ExSsspBIpFwwzr80MHDn+fcy6zIiWwW8el9XW+F/Ktd2FpWsM3OssoV9dw1zDQEWoQxuLzZnKejFYSnt2oAc5GZPmJWHyQ+RDD1cORFLucs24d8ukmblCGdLmXEIcPzBZOegYWLWwKBgQCQf2HQ3ZPux85FzjQHtHUv/EPJ1dQwuJRN4heCsiMoS5iabqqPoen6fAYErVzTHM6nyGyu90oSwQCFgYBh8LLlU+FlFKveQGYPRhNI6Qc0iu4AoKjSIc1by+2bXL9/PGdE709OWVDmI+vQz+7bANa3W0UBHMnnMw4fc3YmjBo8lQKBgQCyP3jS55rO/bQoGMQuQMrXivj3lsShB9qxSDd+FPU6x4PT5SZAIlt4EaJ/KShRYuOjI4f6FPShzlX0SAyiXFPgI98HF3PqirUfpC2G4FBSliEfQnvMEuiB2+3+9ejya/IF6zU8SVzVJJ8ZUR80+MMrdd+vrs5VYWEyhOR4lN+3kwKBgB471kJOZC9YMWfaXSyKSahnlBHQyuTzJZRaKUqrMquKFrbyXcEoevwCmVk5t1I+1nZ7gm1mXmhfmdIYPnOBBKD2pSrIn8aGGJmBp012yQEuIXiDQBLOjJKOjScvG8xJlm6waW7K+7BG51FkWKWcbDkq+BJ54xcZmIls/ILNWS8T";
var sign = CryptoJS.MD5(result).toString().toUpperCase();
console.log(sign)
pm.expect(jsonData.sign).to.eql(sign);
});
二、Jmeter工具
1.用户自定义变量
2.CSV批量添加
3.函数
1.计数器函数
使用计数器变量

2.随机数函数

3.时间函数

4.JDBC请求
第一步 添加数据库驱动包
第二部 设置连接参数
第三步 添加JDBC请求
第四步 查看结果集合

5. 使用JDBC中的请求结果作为接口参数
添加变量名
添加调试取样器
查看查询结果
使用结果变量

6.逻辑控制器
1.if逻辑控制器
创建if逻辑控制器,if逻辑控制器和http请求是父子关系

2.foreach控制器
添加一组变量
添加foreach控制器
添加请求

3.循环控制器

7.定时器
1.同步定时器
需求:同一时刻100个用户去访问系统的查询所有学院信息功能,统计高并发情况下平均响应时 间以及错误率(高并发)
设置100个线程

添加请求同步器

2.常数吞吐量定时器
需求:一个用户以20QPS(==20次/S)的频率访问学生管理系统服务器,持续15秒,统计服务器的平均 响应时间


实战
场景1:模拟半小时之内1000个用户访问服务器资源,要求平均响应时间在3000ms内,且措误率为0

场景2:模拟100个用户同时访问服务器资源,要求平均响应时间在3000s内,且错误率为0


场景3:模拟2个用户以20QPS的频率访问服务器资源持续10秒,要求平均响应时间在3000s内,错误率为0

