zoukankan      html  css  js  c++  java
  • 【pytest】(十一)fixture参数化-巧用params和ids的真接口自动化实战

    在上一篇文章中聊到了fixture的一些用法,利用params和ids这2个参数来实现对于测试数据初始的一些需求。
    【pytest】(十)fixture参数化-巧用params和ids优雅的创建测试数据
    但是文中的示例代码并不是真正的接口测试,只是用了一些print描述了下我的设想,以及一定的验证,缺乏实际应用。

    刚好最近抽空在写一些接口自动化,正好拿一个接口实践下。
    这个接口是一个列表接口,根据status的传参,可以返回对应状态的数据,其中:待处理-10,处理中-20,已完成-30
    代码部分的话 就分2部分贴出来吧。

    一、fixture

    先看代码

    import pytest
    from faker import Faker
    from util.mysql_operating import DB
    
    fake = Faker()
    
    
    def init_data(fixture_value):
        if fixture_value == 10:
            return "untreated"
        elif fixture_value == 20:
            return "processing"
        elif fixture_value == 30:
            return "done"
    
    
    @pytest.fixture(params=[10, 20, 30], ids=init_data)
    def init_data_query_by_status(request):
        status = request.param
        print("fixture 参数", status)
        uid = fake.pyint(min_value=10086, max_value=99999, step=1)
        order_sn = "CK" + fake.pystr(min_chars=19, max_chars=19)
    
        real_sql = """INSERT INTO `tcwms`.`sm_outbound_order`(`id`, `out_id`, `order_sn`, `admin_id`, `admin_name`, `total_price`,
         `remark`, `status`, `type`, `use_type`, `mchid`, `wh_id`, `add_time`, `update_time`, `out_time`, `to_id`, `to_name`
         , `verify_status`, `verify_time`, `verify_ad_id`, `verify_ad_name`, `posting_status`, `posting_time`, 
         `posting_ad_id`, `posting_ad_name`, `is_valid`, `finance_verify_status`, `finance_verify_time`, `finance_verify_remarks`,
          `finance_verify_ad_id`, `finance_verify_ad_name`, `pay_status`) 
          VALUES ({}, 1752, '{}', 572, '', 619.00, '', {}, 1, 0, {}, {}, '2019-06-20 09:55:58', '2019-06-20 09:55:58',
           '2019-01-01 00:00:00', 210, '', 1, '2019-01-01 00:00:00', 0, '', 1, '2019-01-01 00:00:00', 0, '', 1, 0,
            '0000-00-00 00:00:00', '', 0, '', 0);""".format(uid, order_sn, status, 6001, 1)
    
        db = DB()
        db.insert_by_sql(real_sql)
        yield status
        real_delete_sql = "DELETE FROM `tcwms`.`sm_outbound_order` WHERE id={};".format(uid)
        db.delete_by_sql(real_delete_sql)
        db.close()
    
    

    代码比较多,但是结构很简单。
    这个fixture的功能就是:在case执行前插入对应状态的测试数据,然后case执行过后,删掉插入的测试数据。

    • 用了下faker库,造一些测试数据。
    • DB操作我是用pymysql库去做一些封装,具体就不看了,反正就是用来执行sql语句的。
    • sql语句就是个字符串str,用format去格式化。
    • init_data就是返回不同的id,以便我用-k命令时候使用
    • yield把参数status返回出来

    二、case部分

    case部分我就只贴出来测试case的代码了,知道意思就行:传参,请求接口,断言

    def test_query_by_status(init_data_query_by_status):
        """
        查询状态,10-待处理;20-处理中;30-已完成
        """
        payload = {
            "status": init_data_query_by_status
        }
        r = requests.post(QA_URL + API_URL, json=payload, headers=HEADER)
        result = r.json()
        res_status = jmespath.search("row.taskListOfPage.resultData[*].status", result)
        res_mchid = jmespath.search("row.taskListOfPage.resultData[0].mchid", result)
        assert_result = loop_list_same_elements(init_data_query_by_status, res_status)
    
        assert assert_result is True
        assert res_mchid == 6001
    
    
    if __name__ == "__main__":
        pytest.main(["-s", "test_wms_outbound_task_list.py::test_query_by_status"])
    
    • payload 里就是传参了,在fixture函数init_data_query_by_status中我们返回了status
    • loop_list_same_elements()这个方法是我封装的一个判断列表返回的所有数据都是否都是一个状态用的。
    • jmespath,用了jmespath库,可以方便的提取json,详细用法在之前的文章有写。

    三、运行

    先运行全部的参数,main方法里就不要加-k

    if __name__ == "__main__":
        pytest.main(["-s", "test_wms_outbound_task_list.py::test_query_by_status"])
    

    运行一下:

    collecting ... collected 3 items
    
    test_wms_outbound_task_list.py::test_query_by_status[untreated] 
    test_wms_outbound_task_list.py::test_query_by_status[processing] 
    test_wms_outbound_task_list.py::test_query_by_status[done] 
    
    ============================== 3 passed in 1.00s ==============================
    
    Process finished with exit code 0
    
    fixture 参数 10
    
      执行的sql: INSERT INTO `tcwms`.`sm_outbound_order`(`id`, `out_id`, `order_sn`, `admin_id`, `admin_name`, `total_price`,     `remark`, `status`, `type`, `use_type`, `mchid`, `wh_id`, `add_time`, `update_time`, `out_time`, `to_id`, `to_name`     , `verify_status`, `verify_time`, `verify_ad_id`, `verify_ad_name`, `posting_status`, `posting_time`,      `posting_ad_id`, `posting_ad_name`, `is_valid`, `finance_verify_status`, `finance_verify_time`, `finance_verify_remarks`,      `finance_verify_ad_id`, `finance_verify_ad_name`, `pay_status`)       VALUES (17288, 1752, 'CKpNInphuUHePrYnDHlXw', 572, '', 619.00, '', 10, 1, 0, 6001, 1, '2019-06-20 09:55:58', '2019-06-20 09:55:58',       '2019-01-01 00:00:00', 210, '', 1, '2019-01-01 00:00:00', 0, '', 1, '2019-01-01 00:00:00', 0, '', 1, 0,        '0000-00-00 00:00:00', '', 0, '', 0);
    PASSED   [ 33%]  
    
    执行的sql: DELETE FROM `tcwms`.`sm_outbound_order` WHERE id=17288;
    
    
    fixture 参数 20
    
      执行的sql: INSERT INTO `tcwms`.`sm_outbound_order`(`id`, `out_id`, `order_sn`, `admin_id`, `admin_name`, `total_price`,     `remark`, `status`, `type`, `use_type`, `mchid`, `wh_id`, `add_time`, `update_time`, `out_time`, `to_id`, `to_name`     , `verify_status`, `verify_time`, `verify_ad_id`, `verify_ad_name`, `posting_status`, `posting_time`,      `posting_ad_id`, `posting_ad_name`, `is_valid`, `finance_verify_status`, `finance_verify_time`, `finance_verify_remarks`,      `finance_verify_ad_id`, `finance_verify_ad_name`, `pay_status`)       VALUES (65242, 1752, 'CKOcOngjWxWxQHsaradMd', 572, '', 619.00, '', 20, 1, 0, 6001, 1, '2019-06-20 09:55:58', '2019-06-20 09:55:58',       '2019-01-01 00:00:00', 210, '', 1, '2019-01-01 00:00:00', 0, '', 1, '2019-01-01 00:00:00', 0, '', 1, 0,        '0000-00-00 00:00:00', '', 0, '', 0);
    
    PASSED  [ 66%]  
    
    执行的sql: DELETE FROM `tcwms`.`sm_outbound_order` WHERE id=65242;
    
    
    fixture 参数 30
    
      执行的sql: INSERT INTO `tcwms`.`sm_outbound_order`(`id`, `out_id`, `order_sn`, `admin_id`, `admin_name`, `total_price`,     `remark`, `status`, `type`, `use_type`, `mchid`, `wh_id`, `add_time`, `update_time`, `out_time`, `to_id`, `to_name`     , `verify_status`, `verify_time`, `verify_ad_id`, `verify_ad_name`, `posting_status`, `posting_time`,      `posting_ad_id`, `posting_ad_name`, `is_valid`, `finance_verify_status`, `finance_verify_time`, `finance_verify_remarks`,      `finance_verify_ad_id`, `finance_verify_ad_name`, `pay_status`)       VALUES (26399, 1752, 'CKimCduBGktGeCOZyxbhE', 572, '', 619.00, '', 30, 1, 0, 6001, 1, '2019-06-20 09:55:58', '2019-06-20 09:55:58',       '2019-01-01 00:00:00', 210, '', 1, '2019-01-01 00:00:00', 0, '', 1, '2019-01-01 00:00:00', 0, '', 1, 0,        '0000-00-00 00:00:00', '', 0, '', 0);
    
    PASSED        [100%]  
    
    执行的sql: DELETE FROM `tcwms`.`sm_outbound_order` WHERE id=26399;
    
    

    我手动进行了空格分隔下,方便查看。
    可以看到,case根据参数化运行了3次。在每一次的执行当中,都是这样的顺序:

    • 执行插入sql
    • 执行测试
    • 执行删除sql

    接下来,我用-k只运行 status-20的case,id也就是processing:

    if __name__ == "__main__":
        pytest.main(["-s", "-k", "processing", "test_wms_outbound_task_list.py::test_query_by_status"])
    

    运行结果:

    collected 3 items / 2 deselected / 1 selected                                                                                                                                
    
    test_wms_outbound_task_list.py 
    
    fixture 参数 20
    
      执行的sql: INSERT INTO `tcwms`.`sm_outbound_order`(`id`, `out_id`, `order_sn`, `admin_id`, `admin_name`, `total_price`,     `remark`, `status`, `type`, `use_type`, `mchid`
    , `wh_id`, `add_time`, `update_time`, `out_time`, `to_id`, `to_name`     , `verify_status`, `verify_time`, `verify_ad_id`, `verify_ad_name`, `posting_status`, `posting_time`,
          `posting_ad_id`, `posting_ad_name`, `is_valid`, `finance_verify_status`, `finance_verify_time`, `finance_verify_remarks`,      `finance_verify_ad_id`, `finance_verify_a
    d_name`, `pay_status`)       VALUES (32128, 1752, 'CKQLrmWALMTjPDLjtCHKh', 572, '', 619.00, '', 20, 1, 0, 6001, 1, '2019-06-20 09:55:58', '2019-06-20 09:55:58',       '2019-0
    1-01 00:00:00', 210, '', 1, '2019-01-01 00:00:00', 0, '', 1, '2019-01-01 00:00:00', 0, '', 1, 0,        '0000-00-00 00:00:00', '', 0, '', 0);
    
    .  
    
    执行的sql: DELETE FROM `tcwms`.`sm_outbound_order` WHERE id=32128;
    
    
    =================================== 1 passed, 2 deselected in 0.32s ======================================
    

    可以看到,只运行了status=20的case。

    以上就是实际的例子了。后面可能还会遇到更多复杂的情况,届时再分享。

  • 相关阅读:
    wxpython 支持python语法高亮的自定义文本框控件的代码
    小米平板6.0以上系统如何不用Root激活Xposed框架的步骤
    vivo4.0系统怎么不ROOT激活Xposed框架的教程
    oppo设备怎么样无需root激活XPOSED框架的教程
    OPPO A7x在哪里开启usb调试模式的详细经验
    python将两个数组合并成一个数组的两种方法的代码
    (最详细)小米MIX的Usb调试模式在哪里打开的教程
    (简单)华为荣耀9i LLD-AL20的Usb调试模式在哪里开启的方法
    linux c ---raise 使用范例的代码
    oppo8.0系统怎么无需Root激活Xposed框架的经验
  • 原文地址:https://www.cnblogs.com/pingguo-softwaretesting/p/13953988.html
Copyright © 2011-2022 走看看