项目为某内控公司要求并发测试,编写多线程访问接口,并生成Excel报告的脚本,记录基本步骤。
若有需要写UI自动化,接口自动化,多线程,服务器测试定时脚本等等,可联系本工具熊。
分五步操作实现50个或更多用户并发操作,代码可直接运行
①打开网页,获取到后端给的cookie;
②登录用户,保持链接;
③业务操作,访问业务接口;
④将上述三步添加到多线程任务中,集中执行,记录数据;
⑤将多线程执行记录生成表格;
import xlwt
import json
import random
import threading
import time
import requests
# ip与passwd为企业保密内容范畴,有需要私聊。
ip = '****'
passwd = '****'
time_now = str(time.time()).replace('.','')[0:13]
now_time= str(time.strftime('%Y-%m-%d %H:%M:%S'))
list = []
def need_Verify_Code(): # 获取cookie
url = "http://" + ip + "/nky/service/session/needVerifyCode"
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive",
"Host": ip,
"Referer": "http://" + ip + "/nky/mobile/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/80.0.3987.122 Safari/537.36",
}
response = requests.request("GET", url, headers=headers)
header = eval(str(response.headers)) # 将请求后的字符类型先简单转成str,再换成dict
set_cookie = header['Set-Cookie']
cookie = set_cookie[0:43]
return cookie
def wx_bind(cookie,user): # H5应用登录
url = "http://"+ip+"/nky/service/session/wxbind"
payload = {
"userName": user,
"password": passwd,
}
header = {
"Accept": "application/json",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive",
"Content-Length": "47",
"Content-Type": "application/json; charset=utf-8",
"Cookie": cookie,
"Host": ip,
"Origin": "http://" + ip,
"Referer": "http://" + ip + "/nky/mobile/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/80.0.3987.122 Safari/537.36",
}
response = requests.request("POST", url, data=json.dumps(payload), headers=header)
# print('登录成功')
def add_apply(cookies, user, userid, i): # 业务请求,新增单据,参数i用于记录线程号码
url = "http://" + ip + "/nky/service/BudgetApplication"
payload = {
"applyDate": time_now,
"departmentId": 10008,
"createdUserId": userid,
"isPurchase": "false",
"isContract": "false",
"isReimburse": "true",
"billFlowDefineId": 1,
"description": "1",
"remark": "test",
"attachments": [],
"amount": 1,
"fiscalYearId": 10003,
"schoolYearId": "null",
"budgetApplicationItems": [{"budgetItemId": 10062, "amount": 1}],
}
headers = {
"Accept": "application/json",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive",
"Content-Length": "579",
"Content-Type": "application/json; charset=utf-8",
"Cookie": cookies,
"Host": ip,
"Origin": "http://"+ip,
"Referer": "http://"+ip+"/nky/mobile/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/80.0.3987.122 Safari/537.36",
}
begin_time = str(time.strftime("%Y-%m-%d %H:%M:%S"))
response = requests.request("POST", url, data=json.dumps(payload), headers=headers)
end_time = str(time.strftime("%Y-%m-%d %H:%M:%S"))
print(response)
bill_id = response.text
has_time = response.elapsed.microseconds # 获取响应时间
has_time = str(has_time / 1000000) # 微秒换成秒,方便理解
response = str(response)
assert "200" in response, response
# 业务请求需要的数据保存在message中,添加到list中用于编写表格
message =("线程"+str(i), bill_id, has_time, user,begin_time, end_time)
list.append(message)
def all(counter): # 将前三个任务放在一起,对用户进行参数化,方便多线程使用。参数counter为线程号码
# 数据库只有这几个数据,若成千上万用户可考虑读取Excel表中数据,此处用字典方便理解
user_and_id = {
"mahuateng": 10000,
"mayun": 10001,
"liyanhong": 10002,
"dinglei": 10003,
"zhangxiaolong": 10004,
"zhangxiaohu": 10005,
"zhangxiaojun": 10006,
"wangxing": 10007,
"wangwenjing": 10008,
"zhaoxiaoyun": 10009,
"zhaoxiaofeng": 10010,
"zhaoxiaoyu": 10011,
"zhaoxiaolei": 10012,
"zhaoxiaodian": 10013,
"dongmingzhu": 10014,
"leijun": 10015,
"leiming": 10016,
"chendongxue": 10017,
}
user = random.sample(user_and_id.keys(), 1)[0] # 随机获取一个用户,获取dict的键名称
user_id = user_and_id[user] # 根据用户查出id 给下个方法使用
co = need_Verify_Code()
wx_bind(co, user)
add_apply(co, user, user_id , counter)
def write_book(): # 编写Excel
wb = xlwt.Workbook(encoding='utf-8')
ws = wb.add_sheet('多线程表格')
ws.write(0,0,label='线程数')
ws.write(0,1,label='单据号')
ws.write(0,2,label='响应时间')
ws.write(0,3,label='用户')
ws.write(0,4,label='起始时间')
ws.write(0,5,label='结束时间')
a = 1
for index in list:
print(index)
ws.write(a, 0, index[0])
ws.write(a, 1, int(index[1])) # 字符类型让表格看起来不会有警告
ws.write(a, 2, float(index[2]))
ws.write(a, 3, index[3])
ws.write(a, 4, index[4])
ws.write(a, 5, index[5])
a += 1
ws.col(3).width = 3000
ws.col(4).width = 5000
ws.col(5).width = 5000
# 因为Excel有表头,格式,不好处理批量精准插入数据,因此执行需要修改Excel名称,若重复则会失败
wb.save('automation10.xlsx')
class myThread (threading.Thread): # 菜鸟上copy的多线程类
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print ("开启线程: " + self.name)
# 获取锁,用于线程同步
threadLock.acquire()
# 释放锁,开启下一个线程
threadLock.release()
all(self.counter)
threadLock = threading.Lock()
threads = []
for i in range(1, 51): # 根据循环数量添加多线程数
t1 = myThread(i, "thread"+str(i), str(i))
t1.start()
threads.append(t1)
# 等待所有线程完成
for t in threads:
t.join()
print("退出主线程")
write_book()