框架介绍
自动化处理的问题&整体思路
待解决的问题:
网页支付+收银台目前接入了超过10+的大类支付方式160多种小支付方式,后台支持43种货币,支付方式接入的和回归+三方渠道金额校验需要花费大量的时间。在人力不充足的情况下尽量做到多的覆盖
整体思路:
通过request框架封装一次下单接口的方法,把支付方式+货币变成变成可选输入,通过excel_ddt驱动的方式维护支付方式和支持的货币,再通过渠道服务提供的支付金额验证的接口断言,实现每次支付方式接入和版本测试完成的时候对PayPal,adyen等多种支付方式的多货币进行全量覆盖
项目实战展示
整体思路:下单接口封装+excel数据驱动+allure报告输出用例结果(request+pytest+allure+panda)
1、下单接口封装
封装单个接口把下单接口和参数化的内容区分开来,用例数据驱动的时候直接控制传参维护即可
def create_order(token, app_id, app_uid, mall_id, role_id, product_id, paymentAdditionData="",
trade_type="NATIVE", pay_type=300035, pay_subtype="CARD#VISA",
currency="IDN(IDR)", quantity=1,
redirect_url="xxxxx",
language="en"):
url = "xxxxxx"
payload = {
"appId": app_id,
"appUid": app_uid,
"mallId": mall_id,
"roleId": role_id,
"tradeType": trade_type,
"payType": pay_type,
"paySubType": pay_subtype,
"productId": product_id,
"currency": currency,
"quantity": quantity,
"redirectUrl": redirect_url,
"language": language,
"paymentAdditionData": paymentAdditionData
}
log.info(f"正在创建订单请求参数为{payload}")
headers = {
'Token': token,
'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
'Content-Type': 'application/json',
'Accept': '*/*'
}
response = requests.post(url, headers=headers, json=payload)
log.info(f"创建订单完成状态码为{response}请求完成响应参数为{response.text}")
return response.text
2、pytest+excel数据驱动
pytest参数化+excel数据ddt驱动,重复执行每个支付方式下支持货币的下单接口,如果不支持这个货币则通过pytest.skip跳过该条用例执行
3、金额校验维护(暂时)
payermax目前借助urllib.parse库对URL进行解析,获取嵌套在三方渠道返回在URL中的金额信息,其他支付方式不支持,后续账号支付组开发对应的金额核对接口对金额进行断言
def parse_query_from_url(url):
log.info(f"正在解析{url}")
parsed_url = urllib.parse.urlparse(url)
if parsed_url.fragment:
parsed_query = urllib.parse.parse_qs(parsed_url.fragment.split('?')[-1])
else:
parsed_query = urllib.parse.parse_qs(parsed_url.query)
return parsed_query
4、payermax用例
下单用例同意维护在一个Test类下面,把通用的用户可能会替换的参数写为属性值,如果后续游戏有变动方便替换,目前是对每个支付渠道设置一个单独的测试函数和ddt+断言,后续有统一的断言数据后可以合并简化代码结构完全通过excel维护
class Test_CreatOrder:
token = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50IjoiYTE2MjE2MzE2NDE2NTE2QDE2My5jb20iLCJhdWQiOiJ1c2VyIiwiY2xpZW50X2lkIjoiZ2FtZXBheV9sZ2xvIiwiZXhwIjoxNzE1OTUwNTY3LCJpYXQiOjE3MTMzNTg1NjcsImlzcyI6InB1cCIsImp0aSI6IjJ2M2g1MmdiMnZsNmNxcmt1YzAwMDNrMSIsImxpbGl0aF9pZCI6Mjg1MDcxLCJsaWxpdGhfdG9rZW4iOiJGU3liSEllaVFiTGJia1JabWtzOE01dUVQRllQaXFVU3dpRkF2dHVKd1oyOSs3dTJNcUsyKysvMTlPSFZuczhvIiwibmJmIjoxNzEzMzU4NTY3LCJ0b2tlbl90eXBlIjowfQ.wnolaNiCdiFKBeYNqchN6KnQOBQRCG15z9gK4yjLWSxYD7LHW1PYqmZBX7dBmoRYd7EKOaM7g8sOGGX3Me-6W635ElQ0Qy5w6joYO-jr3H6NS5q0iELcoqfo_YzjNPgvAVS4F3yPdN1VbGcu1VrEFudAX-afG5oG3R9LL3Rhd-U'
app_id = 9130660
app_uid = 1050005
mall_id = 5
role_id = "1320093"
product_id = "diamond_5"
@pytest.mark.parametrize('currency,except_result', payermax_currency_data)
def test_payermax(self, currency, except_result):
# 维护下单支付参数
pay_type = 300035
pay_subtype = "CARD#VISA"
# 如果支付类型不支持改货币,跳过改条用例
if except_result == '失败': # 假设失败的条件是except_result等于字符串'失败'
log.info(f"支付方式{pay_subtype}子类型{pay_subtype}不支持{currency}货币预期创建订单失败,跳过用例")
pytest.skip(f"不支持改货币,跳过此用例")
try:
order_result = create_order(self.token, self.app_id, self.app_uid, self.mall_id, self.role_id,
self.product_id, pay_type=pay_type, pay_subtype=pay_subtype, currency=currency)
# 确保order_result是字典
if isinstance(order_result, str):
order_result = json.loads(order_result)
log.info(f"创建{currency}订单", order_result)
# 控制API频率
time.sleep(1)
query_result = get_product_price(mall_id=self.mall_id, currency=currency, product_id=self.product_id)
# 确保query_result是字典
if isinstance(query_result, str):
query_result = json.loads(query_result)
log.info(f"请求{currency}", query_result)
# 控制API频率
time.sleep(1)
# 确保price_amount是整数
price_amount = float(float(query_result["data"]["originalUnitPrice"]))
# 根据支付方式不同在此添加断言或其他测试逻辑(payermax)+通用断言
assert_code =order_result["code"]
pay_url_amount = float(parse_query_from_url(order_result['data']['payUrl'])['amount'][0])
log.info(f"断言获取价格阶梯金额为{price_amount},payermaxurl金额为{pay_url_amount},断言获取的状态码为{assert_code}")
# 断言payermax的url金额和请求正确返回的状态码
assert price_amount == pay_url_amount
assert assert_code == 0
except json.JSONDecodeError as e:
log.error("JSON解析错误:", e)
except KeyError as e:
log.error("缺少预期的键:", e)
except Exception as e:
log.error("发生异常:", e)
评论区