zoukankan      html  css  js  c++  java
  • locust 实战:完成用户登录并下单的流程

    locust 实战:用户登录并下单

    涉及内容:

    1、session信息关联

    2、用户数据参数化

    3、对响应数据进行检查点设置

    具体代码如下:

    #-*-encoding:utf-8-*-
    from locust import HttpLocust,TaskSet,task
    from locust.clients import HttpSession
    import re,random,json
    import MyLog
    
    
    """
    MyLog 自定义日志
    使用HttpSession对象提交接口请求进行session信息的关联,
    然后通过json或re 对页面内容进行提取,并把返回的结果作为检查点进行比较
    思路:
    1.将下单的每个步骤对应的请求分别封装到不同的方法中,并在方法中设置检查点进行判断响应结果是否正确
    2.将用户信息在on_start()方法中初始化,如果数据量少的话,可以直接在脚步中直接配置,如果用户数据量大的话,可以放到txt文档中,再on_start()中读取即可
    3.将接口中的用户信息参数进行参数化
    4.按下单流程的各个步骤对应的方法,按顺序进行调用
    5.调用压测脚本
    
    """
    
    
    
    class loginHttpSession(TaskSet):
    	#登录并购买商品压力测试
    
    
    	def on_start(self):
    		"""
    		测试数据初始化
    		1.创建session会话,提供给后面的请求
    		2.初始化请求头的信息
    		3.初始化用户信息(用户信息参数化)
    		4.引用自定义日志
    		"""
    		self.session=HttpSession(base_url="http://localhost:8081/tshop/")
    
    		self.header={
    		"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
    		"Accept-Language": "zh-CN,zh;q=0.9",
    		"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
    		"Accept-Encoding": "gzip, deflate, br"
    		}
    	
    		self.userinfo={
    		0:["123@qq.com","123456"],
    		1:["223@qq.com","123456"],
    		2:["333@qq.com","123456"]
    		}
    
    		self.log=MyLog.MyLog().get_logger()
    
    
    	
    	def get_user_info(self):
    		#获取随机用户ID
    		user_id=random.randint(0,len(self.userinfo)-1)
    		return user_id
    
    
    
    
    	def index(self):
    		#打开商城首页
    		return self.session.get("/")
    
    
    
    	def input_username(self,loginToken,uname):
    		#进入输入用户名页面
    		#需要传送session和登录token值
    		#返回响应信息response,和userId
    		input_url="index.php"
    		param={
    		"con":"ajax",
    		"act":"account",
    		# "account":"123@qq.com"
    		"account":uname,   #参数化用户名信息
    		}
    
    		# self.log.debug("[input_username]:userId=%s" %userId)   #打印日志
    		# response=self.session.post(input_url,params=param,headers=self.header)
    		with self.session.post(input_url,params=param,headers=self.header,catch_response=True) as response:
    			#获取请求详情数据,并设置检查点
    			print response.text
    			response_value=response.text
    			print type(response_value)
    			#由于返回的数据是unicode类型,也就是字符串,所以只能截取有效数据进行后面的检查点的判断
    			status=response_value[response_value.find('"status":')+len('"status":'):response_value.find(",")]
    			msg=response_value[response_value.find('"msg":"')+len('"msg":"'):response_value.find('"}')]
    			if status!="false":
    				response.failure("input_username: status error!")
    			elif msg!="u6b64u7528u6237u5df2u7ecfu6ce8u518c":
    				response.failure("input_username: msg error!")
    
    			return response,uname
    
    
    
    
    
    	def submit_login(self,loginToken,uname,upwd):
    		#输入用户名和密码提交登录
    		#需要传递loginToken,和userId用于用户登录
    		#返回响应信息response,和userId
    		login_url="index.php?con=simple&act=login_act"
    
    		bodys={
    		"redirectURL":"/tshop/",
    		# "account":"123@qq.com",
    		# "password":"123456",
    		"account":uname,     #参数化用户名
    		"password":upwd,	#参数化密码
    		"tiny_token_login":loginToken,
    		}
    		# self.log.debug("[submit_login]:userId=%s" %userId)
    
    		with self.session.post(login_url,data=bodys,headers=self.header,catch_response=True) as response:
    			text=response.text
    			page_text=re.compile(r'<div class="sub-1">(.+)?-')
    			page_userinfo=page_text.search(text)
    			userinfo=page_userinfo.group(1)
    			print userinfo
    			print uname
    			if userinfo.find(uname)<0:   #str的find方法如果找不到元素,返回值为-1,所以判断小于0表示,在userinfo中无登录的用户名
    				response.failure("submit_login: not found username in page!")
    			return response,uname
    
    
    
    	def go_goods_details(self):
    		#进入商品详情页面
    		#返回响应数据
    		goodsDetails_url="index.php"
    		params={
    		"con":"index",
    		"act":"product",
    		"id":"16"
    		}
    
    		# response=self.session.get(goodsDetails_url,data=params,headers=self.header)
    		with self.session.get(goodsDetails_url,data=params,headers=self.header,catch_response=True) as response:
    			text=response.text
    			page_text=re.compile(r'</span><b class="cart-total red" >(.+)?</b></span></span></div>')
    			page_price=page_text.search(text)
    			price=page_price.group(1)
    			if price <100:
    				response.failure("go_goods_details: not found price!")
    
    			return response
    
    
    	def add_goods_tips(self,loginToken=None):
    		#在商品详情页面,点击进入到确认订单页面
    		#返回用户购物车清单的商品信息
    		goods_tips_url="index.php?con=index&act=goods_add&id=61&num=3"
    		with self.session.get(goods_tips_url,headers=self.header,catch_response=True) as response:
    			text=response.text
    			page_text=re.compile(r"<li >(.+)?<em></em><i></i></li>")
    			page_info=page_text.search(text)
    			value=page_info.group(1)
    			if value!="4、订购完成":
    				response.failure("add_goods_tips: not found 4、订购完成")
    			return response
    
    
    
    	def fill_order_info(self):
    		#进入到填写订单信息页面
    		#使用正则表达式,抓取页面返回的order_Token
    		#返回响应数据与order_Token
    
    		fill_order_url="index.php?con=simple&act=order&cart_type=cart"
    
    		with self.session.get(fill_order_url,headers=self.header,catch_response=True) as response:
    
    			order_re=re.compile(r"'tiny_token_order' value='(.+)?'/>")
    			order_token=None   #order_token赋默认值为None,如果取不到order_token以便下面进行判断,为None则抛出错误
    			order_token=order_re.search(response.text).group(1)
    			if order_token==None:
    				response.failure("fill_order_info: not found order_token")
    
    			return response,order_token
    
    
    	def submit_order(self,orderToken,uname):
    		#提交订单
    		#需传递填写订单信息页面的orderToken,对提交订单进行参数化
    		#根据userId,登录的userId来区分不同用户的收货地址id
    		#返回响应信息,与orderToken
    		sub_order_url="index.php?con=simple&act=order_act"
    
    		bodys={
    		"address_id":"30",
    		"payment_id":"1",
    		"user_remark":"",	
    		"invoice_type":"0",
    		"invoice_title":"",
    		"cart_type":"",
    		"tiny_token_order":orderToken
    		}
    		
    		#根据不同的userId更新参数中的地址id,确保每个用户的收货地址正确
    		if uname=="123@qq.com":
    			bodys["address_id"]="30"
    		elif uname=="223@qq.com":
    			bodys["address_id"]="31"
    		elif uname=="333@qq.com":
    			bodys["address_id"]="32"
    		else :
    			print "userId not found !!!"
    		# self.log.debug("[submit_order]:userId=%s,address_id=%s" %(userId,bodys["address_id"]))
    		
    		with self.session.post(sub_order_url,data=bodys,headers=self.header,catch_response=True) as response:
    			text=response.text
    			textview=re.compile(r'<span><i class="icon-success-48"></i>(.+)?</span>')
    			re_result=textview.search(text)
    			page_info=re_result.group(1)
    			# if page_info!="订单已成功提交!":
    			# 	response.failure("submit_order:not found 订单已成功提交!")
    			return response,orderToken
    
    
    
    	def logout(self):
    		#下单成功后,退出登录
    		logout_url="index.php?con=simple&act=logout"
    		with self.session.get(logout_url,headers=self.header) as response:
    			return response
    
    	@task
    	def go_shopping(self):
    		#购买商品流程:登录->进入商品详情页面->将商品添加到购物车->进入填写订单信息页面->提交订单
    
    		user_id=self.get_user_info()	#获取用户id
    		username=self.userinfo[user_id][0]
    		upassword=self.userinfo[user_id][1]
    
    		self.index()	#进入商城首页
    
    		laster_url="index.php?con=simple&act=login"
    
    		first_reponse=self.session.get(laster_url,headers=self.header)
    		lg_page=first_reponse.text
    
    		re_token=re.compile(r"name='tiny_token_login' value='(.+)?'/>")
    		
    		#通过正则表达式获取登录页面的token信息
    		re_result=re_token.search(lg_page)
    		lg_token=None
    		if re_result:
    			lg_token=re_result.group(1)
    
    
    		# #输入用户名页面,并获取login_token 信息
    		inp_username_response=self.input_username(loginToken=lg_token,uname=username)
    		inp_username_userId=inp_username_response[1]   #返回输入用户名时,参数化的userId
    
    
    
    		# # #输入账号、密码,并提交登录
    		sub_login_response=self.submit_login(loginToken=lg_token,uname=username,upwd=upassword)
    		sub_login_userId=sub_login_response[1]  #返回用户登录时,参数化的userId
    
    
    
    		# #进入到商品详情页面
    		goods_details_response=self.go_goods_details()
    		# # print goods_details_response.text
    
    
    
    		# #进入购物车清单页面
    		goods_tips_response=self.add_goods_tips()
    		# # print goods_tips_response.text
    
    
    		# #点击购物车清单页面的-【立即支付】,跳转到填写订单信息页面
    		fill_order_response=self.fill_order_info()
    		orderToken_value=fill_order_response[1]
    
    
    
    		# #点击填写订单信息页面【确认支付】按钮
    		sub_order_response=self.submit_order(orderToken=orderToken_value,uname=username)
    
    
    		#退出用户登录状态
    		logout=self.logout()
    
    
    
    
    class WebUserLocust(HttpLocust):
    	task_set=loginHttpSession
    

      

    创建执行脚本:

    #-*-encoding:utf-8-*-
    import os
    
    
    os.system("locust.exe -f F:\testAndStudy\loginHttpSession.py --host=http://localhost:8081/tshop/")
    

      

     运行结果:

    看看异常的记录日志:

     再看看,我自己设置的locust运行中打印的登录用户信息:

     

    最后,登录商城查看是否有新的订单:

     (特此说明一下,为什么订单时间有时候一致,有时候不一致。这是因为我在参数化时,取的是随机用户id,也就是说,同一秒有时候登录相同的账号进行下单,或者同一秒登录两个不同的账号并下单。

    这个其实是不影响,但觉得有必要说明一下)

  • 相关阅读:
    《CLR via C#》笔记——运行时序列化(2)
    《CLR via C#》笔记——程序集的加载和反射(2)
    《CLR via C#》笔记——线程基础
    《CLR via C#》笔记——AppDomain(1)
    《CLR via C#》笔记——运行时序列化(1)
    《CLR via C#》笔记——程序集的加载和反射(3)
    《CLR via C#》笔记——AppDomain(2)
    C# 3.0 新特性概览
    【JAVASCRIPT】jquery实现新闻滚动效果
    【JAVASCRIPT】jquery实现图片笼罩效果
  • 原文地址:https://www.cnblogs.com/JcHome/p/10690005.html
Copyright © 2011-2022 走看看