Python 自动化测试(三): pytest 参数化测试用例构建

简介: 本文节选自霍格沃玆测试学院内部教材,文末链接进阶学习。在之前的文章中主要分享了 pytest 的实用特性,接下来讲 Pytest 参数化用例的构建。

本文节选自霍格沃玆测试学院内部教材,文末链接进阶学习。

在之前的文章中主要分享了 pytest 的实用特性,接下来讲 Pytest 参数化用例的构建。

如果待测试的输入与输出是一组数据,可以把测试数据组织起来用不同的测试数据调用相同的测试方法。参数化顾名思义就是把不同的参数,写到一个集合里,然后程序会自动取值运行用例,直到集合为空便结束。pytest 中可以使用 @pytest.mark.parametrize 来参数化。

使用 parametrize 实现参数化

parametrize( ) 方法源码:

def parametrize(self,argnames, argvalues, indirect=False, ids=None, \
    scope=None):
  • 主要参数说明

    • argsnames :参数名,是个字符串,如中间用逗号分隔则表示为多个参数名
    • argsvalues :参数值,参数组成的列表,列表中有几个元素,就会生成几条用例
  • 使用方法

    • 使用 @pytest.mark.paramtrize() 装饰测试方法
    • parametrize('data', param) 中的 “data” 是自定义的参数名,param 是引入的参数列表
    • 将自定义的参数名 data 作为参数传给测试用例 test_func
    • 然后就可以在测试用例内部使用 data 的参数了

创建测试用例,传入三组参数,每组两个元素,判断每组参数里面表达式和值是否相等,代码如下:

@pytest.mark.parametrize("test_input,expected",[("3+5",8),("2+5",7),("7*5",30)])
def test_eval(test_input,expected):
    # eval 将字符串str当成有效的表达式来求值,并返回结果
    assert eval(test_input) == expected

运行结果:

plugins: html-2.0.1, rerunfailures-8.0, xdist-1.31.0, ordering-0.6, \
forked-1.1.3, allure-pytest-2.8.11, metadata-1.8.0
collecting ... collected 3 items

test_mark_paramize.py::test_eval[3+5-8] 
test_mark_paramize.py::test_eval[2+5-7] 
test_mark_paramize.py::test_eval[7*5-35] 

============================== 3 passed in 0.02s ===============================

整个执行过程中,pytest 将参数列表 [("3+5",8),("2+5",7),("7*5",30)] 中的三组数据取出来,每组数据生成一条测试用例,并且将每组数据中的两个元素分别赋值到方法中,作为测试方法的参数由测试用例使用。

多次使用 parametrize

同一个测试用例还可以同时添加多个 @pytest.mark.parametrize 装饰器, 多个 parametrize 的所有元素互相组合(类似笛卡儿乘积),生成大量测试用例。

场景:比如登录场景,用户名输入情况有 n 种,密码的输入情况有 m 种,希望验证用户名和密码,就会涉及到 n*m 种组合的测试用例,如果把这些数据一一的列出来,工作量也是非常大的。pytest 提供了一种参数化的方式,将多组测试数据自动组合,生成大量的测试用例。示例代码如下:

@pytest.mark.parametrize("x",[1,2])
@pytest.mark.parametrize("y",[8,10,11])
def test_foo(x,y):
    print(f"测试数据组合x: {x} , y:{y}")

运行结果:

plugins: html-2.0.1, rerunfailures-8.0, xdist-1.31.0, ordering-0.6,\
 forked-1.1.3, allure-pytest-2.8.11, metadata-1.8.0
collecting ... collected 6 items

test_mark_paramize.py::test_foo[8-1] 
test_mark_paramize.py::test_foo[8-2] 
test_mark_paramize.py::test_foo[10-1] 
test_mark_paramize.py::test_foo[10-2] 
test_mark_paramize.py::test_foo[11-1] 
test_mark_paramize.py::test_foo[11-2] 

分析如上运行结果,测试方法 test_foo( ) 添加了两个 @pytest.mark.parametrize() 装饰器,两个装饰器分别提供两个参数值的列表,2 * 3 = 6 种结合,pytest 便会生成 6 条测试用例。在测试中通常使用这种方法是所有变量、所有取值的完全组合,可以实现全面的测试。

@pytest.fixture 与 @pytest.mark.parametrize 结合

下面讲结合 @pytest.fixture 与 @pytest.mark.parametrize 实现参数化。

如果测试数据需要在 fixture 方法中使用,同时也需要在测试用例中使用,可以在使用 parametrize 的时候添加一个参数 indirect=True,pytest 可以实现将参数传入到 fixture 方法中,也可以在当前的测试用例中使用。

parametrize 源码:

def parametrize(self,argnames, argvalues, indirect=False, ids=None, scope=None):

indirect 参数设置为 True,pytest 会把 argnames 当作函数去执行,将 argvalues 作为参数传入到 argnames 这个函数里。创建“test_param.py”文件,代码如下:

# 方法名作为参数
test_user_data = ['Tome', 'Jerry']
@pytest.fixture(scope="module")
def login_r(request):
    # 通过request.param获取参数
    user = request.param
    print(f"\n 登录用户:{user}")
    return user

@pytest.mark.parametrize("login_r", test_user_data,indirect=True)
def test_login(login_r):
    a = login_r
    print(f"测试用例中login的返回值; {a}")
    assert a != ""

运行结果:

plugins: html-2.0.1, rerunfailures-8.0, xdist-1.31.0, ordering-0.6,\
 forked-1.1.3, allure-pytest-2.8.11, metadata-1.8.0
collecting ... collected 2 items

test_mark_paramize.py::test_login[Tome] 
test_mark_paramize.py::test_login[Jerry] 

============================== 2 passed in 0.02s ===============================

Process finished with exit code 0

 登录用户:Tome PASSED           [ 50%]测试用例中login的返回值; Tome

 登录用户:Jerry PASSED           [100%]测试用例中login的返回值; Jerry

上面的结果可以看出,当 indirect=True 时,会将 login_r 作为参数,test_user_data 被当作参数传入到 login_r 方法中,生成多条测试用例。通过 return 将结果返回,当调用 login_r 可以获取到 login_r 这个方法的返回数据。

更多技术文章分享及测试资料点此获取

相关文章
|
3月前
|
人工智能 搜索推荐 数据管理
探索软件测试中的自动化测试框架选择与优化策略
本文深入探讨了在现代软件开发流程中,如何根据项目特性、团队技能和长期维护需求,精准选择合适的自动化测试框架。
168 11
|
1天前
|
机器学习/深度学习 设计模式 API
Python 高级编程与实战:构建微服务架构
本文深入探讨了 Python 中的微服务架构,介绍了 Flask、FastAPI 和 Nameko 三个常用框架,并通过实战项目帮助读者掌握这些技术。每个框架都提供了构建微服务的示例代码,包括简单的 API 接口实现。通过学习本文,读者将能够使用 Python 构建高效、独立的微服务。
|
1天前
|
消息中间件 分布式计算 并行计算
Python 高级编程与实战:构建分布式系统
本文深入探讨了 Python 中的分布式系统,介绍了 ZeroMQ、Celery 和 Dask 等工具的使用方法,并通过实战项目帮助读者掌握这些技术。ZeroMQ 是高性能异步消息库,支持多种通信模式;Celery 是分布式任务队列,支持异步任务执行;Dask 是并行计算库,适用于大规模数据处理。文章结合具体代码示例,帮助读者理解如何使用这些工具构建分布式系统。
|
16天前
|
存储 人工智能 程序员
通义灵码AI程序员实战:从零构建Python记账本应用的开发全解析
本文通过开发Python记账本应用的真实案例,展示通义灵码AI程序员2.0的代码生成能力。从需求分析到功能实现、界面升级及测试覆盖,AI程序员展现了需求转化、技术选型、测试驱动和代码可维护性等核心价值。文中详细解析了如何使用Python标准库和tkinter库实现命令行及图形化界面,并生成单元测试用例,确保应用的稳定性和可维护性。尽管AI工具显著提升开发效率,但用户仍需具备编程基础以进行调试和优化。
186 9
|
2月前
|
人工智能 开发者 Python
Chainlit:一个开源的异步Python框架,快速构建生产级对话式 AI 应用
Chainlit 是一个开源的异步 Python 框架,帮助开发者在几分钟内构建可扩展的对话式 AI 或代理应用,支持多种工具和服务集成。
224 9
|
3月前
|
数据采集 人工智能 自然语言处理
Midscene.js:AI 驱动的 UI 自动化测试框架,支持自然语言交互,生成可视化报告
Midscene.js 是一款基于 AI 技术的 UI 自动化测试框架,通过自然语言交互简化测试流程,支持动作执行、数据查询和页面断言,提供可视化报告,适用于多种应用场景。
755 1
Midscene.js:AI 驱动的 UI 自动化测试框架,支持自然语言交互,生成可视化报告
|
2月前
|
存储 测试技术 API
pytest接口自动化测试框架搭建
通过上述步骤,我们成功搭建了一个基于 `pytest`的接口自动化测试框架。这个框架具备良好的扩展性和可维护性,能够高效地管理和执行API测试。通过封装HTTP请求逻辑、使用 `conftest.py`定义共享资源和前置条件,并利用 `pytest.ini`进行配置管理,可以大幅提高测试的自动化程度和执行效率。希望本文能为您的测试工作提供实用的指导和帮助。
128 15
|
2月前
|
Shell 程序员 开发者
轻松搞定在Python中构建虚拟环境
本教程教你如何使用业界公认的最佳实践,创建一个完全工作的Python开发环境。虚拟环境通过隔离依赖项,避免项目间的冲突,并允许你轻松管理包版本。我们将使用Python 3的内置`venv`模块来创建和激活虚拟环境,确保不同项目能独立运行,不会相互干扰。此外,还将介绍如何检查Python版本、激活和停用虚拟环境,以及使用`requirements.txt`文件共享依赖项。 通过本教程,你将学会: - 创建和管理虚拟环境 - 避免依赖性冲突 - 部署Python应用到服务器 适合新手和希望提升开发环境管理能力的开发者。
158 2
|
3月前
|
机器学习/深度学习 人工智能 jenkins
探索软件测试中的自动化与持续集成
【10月更文挑战第21天】 在软件开发的生命周期中,软件测试扮演着至关重要的角色。随着技术的进步和开发模式的转变,自动化测试和持续集成已经成为提高软件质量和效率的关键手段。本文将深入探讨自动化测试和持续集成的概念、实施策略以及它们如何相互配合以优化软件开发流程。我们将通过分析实际案例,展示这些技术如何在实际项目中发挥作用,以及面临的挑战和解决方案。此外,文章还将讨论未来趋势,包括人工智能在测试领域的应用前景。
105 17
|
3月前
|
机器学习/深度学习 人工智能 算法
深度学习入门:用Python构建你的第一个神经网络
在人工智能的海洋中,深度学习是那艘能够带你远航的船。本文将作为你的航标,引导你搭建第一个神经网络模型,让你领略深度学习的魅力。通过简单直观的语言和实例,我们将一起探索隐藏在数据背后的模式,体验从零开始创造智能系统的快感。准备好了吗?让我们启航吧!
128 3

热门文章

最新文章