侧边栏壁纸
  • 累计撰写 14 篇文章
  • 累计创建 10 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

基于request+pytest的excel驱动的接口自动化

ximu
2024-06-17 / 0 评论 / 0 点赞 / 58 阅读 / 6300 字

框架介绍

自动化处理的问题&整体思路

待解决的问题:

网页支付+收银台目前接入了超过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)

5、allure报告展示

0

评论区