【pytest】(十一)fixture参数化-巧用params和ids的真接口自动化实战

简介: 【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。


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

相关文章
|
1月前
|
运维 应用服务中间件 持续交付
自动化运维的利器:Ansible实战应用
【9月更文挑战第33天】本文将带你深入理解Ansible,一个强大的自动化运维工具。我们将从基础概念开始,逐步探索其配置管理、任务调度等功能,并通过实际案例演示其在自动化部署和批量操作中的应用。文章旨在通过浅显易懂的语言和实例,为读者揭开Ansible的神秘面纱,展示其在简化运维工作中的强大能力。
156 64
|
2月前
|
运维 安全 应用服务中间件
自动化运维的利剑:Ansible实战应用
【9月更文挑战第24天】在现代IT基础设施的快速迭代与扩展中,自动化运维成为提升效率、保障稳定性的关键。本文将深入探讨Ansible这一流行的自动化工具,通过实际案例分析其如何简化日常运维任务,优化工作流程,并提高系统的可靠性和安全性。我们将从Ansible的基础概念入手,逐步深入到高级应用技巧,旨在为读者提供一套完整的Ansible应用解决方案。
|
28天前
|
测试技术
自动化测试项目学习笔记(五):Pytest结合allure生成测试报告以及重构项目
本文介绍了如何使用Pytest和Allure生成自动化测试报告。通过安装allure-pytest和配置环境,可以生成包含用例描述、步骤、等级等详细信息的美观报告。文章还提供了代码示例和运行指南,以及重构项目时的注意事项。
130 1
自动化测试项目学习笔记(五):Pytest结合allure生成测试报告以及重构项目
|
9天前
|
前端开发 数据管理 测试技术
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第27天】本文介绍了前端自动化测试中Jest和Cypress的实战应用与最佳实践。Jest适合React应用的单元测试和快照测试,Cypress则擅长端到端测试,模拟用户交互。通过结合使用这两种工具,可以有效提升代码质量和开发效率。最佳实践包括单元测试与集成测试结合、快照测试、并行执行、代码覆盖率分析、测试环境管理和测试数据管理。
21 2
|
10天前
|
前端开发 JavaScript 数据可视化
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第26天】前端自动化测试在现代软件开发中至关重要,Jest和Cypress分别是单元测试和端到端测试的流行工具。本文通过解答一系列问题,介绍Jest与Cypress的实战应用与最佳实践,帮助开发者提高测试效率和代码质量。
24 2
|
18天前
|
运维 监控 jenkins
运维自动化实战:利用Jenkins构建高效CI/CD流程
【10月更文挑战第18天】运维自动化实战:利用Jenkins构建高效CI/CD流程
|
27天前
|
运维 关系型数据库 MySQL
自动化运维工具Ansible的实战应用
【10月更文挑战第9天】在现代IT运维领域,效率和可靠性是衡量一个系统是否健康的重要指标。自动化运维工具Ansible因其简洁、易用的特性,成为了众多企业和开发者的首选。本文将通过实际案例,展示如何利用Ansible进行日常的运维任务,包括配置管理、软件部署以及批量操作等,帮助读者深入理解Ansible的应用场景及其带来的效益。
|
28天前
|
测试技术 Python
自动化测试项目学习笔记(四):Pytest介绍和使用
本文是关于自动化测试框架Pytest的介绍和使用。Pytest是一个功能丰富的Python测试工具,支持参数化、多种测试类型,并拥有众多第三方插件。文章讲解了Pytest的编写规则、命令行参数、执行测试、参数化处理以及如何使用fixture实现测试用例间的调用。此外,还提供了pytest.ini配置文件示例。
19 2
|
2月前
|
JSON 移动开发 监控
快速上手|HTTP 接口功能自动化测试
HTTP接口功能测试对于确保Web应用和H5应用的数据正确性至关重要。这类测试主要针对后台HTTP接口,通过构造不同参数输入值并获取JSON格式的输出结果来进行验证。HTTP协议基于TCP连接,包括请求与响应模式。请求由请求行、消息报头和请求正文组成,响应则包含状态行、消息报头及响应正文。常用的请求方法有GET、POST等,而响应状态码如2xx代表成功。测试过程使用Python语言和pycurl模块调用接口,并通过断言机制比对实际与预期结果,确保功能正确性。
228 3
快速上手|HTTP 接口功能自动化测试
|
2月前
|
运维 监控 应用服务中间件
自动化运维的新篇章:Ansible Playbooks入门与实战
【9月更文挑战第1天】在追求效率和稳定性的今天,自动化运维已经成为IT行业的必修课。本文将带你走进自动化工具Ansible的世界,通过实战案例深入理解Ansible Playbooks的编写和应用。文章不仅介绍基础概念,更通过具体代码示例,展示如何利用Ansible简化日常运维任务,提升工作效率。无论你是运维新手还是希望深化自动化技能的资深人士,本指南都将为你开启一段新的学习旅程。

热门文章

最新文章

下一篇
无影云桌面