pytest框架的使用

pytest框架

一, pytest框架环境搭建

  1. Pip install pytest

二,pytest框架的使用

1,pytest测试需要遵守的规则:

测试文件要以test_开头

测试类要以 Test开头,并且不能有init方法

测试方法必须要以test_开头

断言使用assert

setup和teardown---这个可以在类中使用,也可以在类外进行使用,该方法每条用例都会执行

setup_module和teardown_module--- 表示只能类外面执行用例过程中,只执行1次

setup_function和teardown_function--- 表示在类外面执行用例过程中,每次都会执行前置和后置

setup_calss和teardown_calss--- 表示在类中执行测试用例前,只执行1次测试前置和测试后置

setup_method和teardown_method--- 表示在类中每次执行测试用例前,测试前置和测试后置都会执行一次

三, 运行命令

运行所有:pytest

运行指定模块: pytest -vs test_0616.py

运行指定目录:pytest -vs ./api/testcase

通过nodeID运行指定的测试函数:

    pytest -vs ./testcase/test_0616.py : : test_04_func

    pytest -vs ./testcase/test_0616.py : : TestLogin : : test_04_func

-q --安静模式,不输出环境信息

-s ---显示打印内容

-sq--简化打印信息

-v  ---节点

    pytest -v ./testcase/test_0616.py : : TestLogin : : test_04_func

-k --匹配用例名称,执行测试用例名称包含(关键字)的所有用例,如pytest test.py -k 关键字

    pytest -k leson---执行测试用例中包含lesson字符的用例

-m --mark,运行带有标记的测试用例

-n --多线程运行(需要先安装pytest-xdist),如pytest test.py -n 2

-x --遇到错误时停止

skip---跳过---跳过测试函数的最简单方法是使用跳过装饰器标记它,可以传递一个可选原因

skipif---有条件的跳过

四 , 参数化

① mark.parametrize参数化

    @pytest.mark.parametrize('变量名',参数列表)

@pytest.mark.parametrize('a,b,c',[(1,2,3),(4,5,6),(7,8,9)])

1.自定义参数

@pytest.mark.parametrize('a,b,expect',[

   [1,1,2],

   [2,2,4],

   [3,3,6],

   [4,4,8],

   [5,5,10]

])

def test_add_list(a,b,expect):

   assert add(a,b)==expect

2.Yaml文档

#用户名请求为空

"url": "http://localhost:5000/login"

"body": '{

           "password":"admin",

           "sex":"男",

           "age":18

        }'

"expect": '{

              "message": {

                  "username": "用户名不能为空"

              }

          }'

def readJson():

   return json.load(open('login.json','r'))['item']

@pytest.mark.parametrize('data',readJson())

def test_json_login(data):

   r=requests.post(

      url=data['request']['url'],

      json=data['request']['body'])

   assert r.json()==data['response'][0]

3.excel表格

import  xlrd

def readExcel():

   data=list()

   book=xlrd.open_workbook('login.xls')

   sheet=book.sheet_by_index(0)

   for item in range(1,sheet.nrows):

      data.append(sheet.row_values(item))

   return data

@pytest.mark.parametrize('data',readExcel())

def test_excel_login(data):

   r=requests.post(

      url=data[0],

      json=json.loads(data[1]))

   assert r.json()==json.loads(data[2])

4.Json数据格式

{

  "item":

  [

    {

      "request":

      {

        "url": "http://localhost:5000/login",

        "body":

        {

          "password":"admin",

          "sex":"男",

          "age":18

        }

      },

      "response":

      [

        {

          "message":

          {

            "username": "用户名不能为空"

          }

        }

      ]

},

import  requests

import  json

def readJson():

   return json.load(open('login.json','r'))['item']

@pytest.mark.parametrize('data',readJson())

def test_json_login(data):

   r=requests.post(

      url=data['request']['url'],

      json=data['request']['body'])

   assert r.json()==data['response'][0]

②fixture参数化

fixture的使用: 用于在测试之前和之后执行设置方法

    @pytest.fixtrue()

    def get_sum():

        return [(1,2,3),(4,5,6)]

    def test_login(get_sum):

        if  "1" in get_sum:

        asster  2==2

    

    pytest.fixtrue(Scope=function)

    什么都不填,默认function

    function: 每次测试运行一次

    class: 每类运行一次

    module:每个模块运行一次

    session:  每个会话运行一次

    权重:function< class<module<session

    @pytest.fixtrue

    在用例中可以直接写上带有fixtrue的函数名,作为参数传入

    使用Tools库里的exccoler函数来读取excel表格

五, 用例执行定制化:

@pytest.mark--给用例类或函数贴标签,可以在每一个模块,每一类,每一个方法和用前添加,方便后续定制化执行测试用例

例:

    @pytest.mark.shop---

    class Testshop:

        pass

@pytest.mark.shop

@pytest.mark.shop_list

装饰器:跳过/有条件跳过

skip---跳过---跳过测试函数的最简单方法是使用跳过装饰器标记它,可以传递一个可选原因

skipif---有条件的跳过

@pytest.mark.skip()--跳过这个函数

@pytest.mark.skipif(1==1)--条件跳过,当1==1时,跳过这个函数

运行时:-m, 加上标签名即可运行指定标签的用例

  pytest  -m “shop_list” 单个标签运行

  pytest  -m “shop_list or shop" 多个标签运行

  pytest  -m “not shop_list” 不运行这个标签

  pytest  -m “not (shop_list or shop_df)” 不运行这些标签

指定用例运行的顺序:

默认是按照字母来执行顺序的,但是我们可以使用pytest_ordering来定制执行顺序

@pytest.mark.run(order=2)

def test_baidu():

    pass

@pytest.mark.run(order=3)

def test_baidu():

    pass

@pytest.mark.run(order=1)

def test_baidu():

    pass

<think>首先,用户的问题是:“我想了解如何在pytest框架使用参数化功能进行测试 请问pytest 参数化测试 使用方法 示例”。这是一个关于pytest参数化测试的查询。 根据系统级指令: - 所有行内数学表达式必须使用$...$格式,但这里没有数学表达式,所以不需要。 - 独立公式必须使用$$...$$格式并单独成段,同样没有数学公式。 - LaTeX语法正确:不适用。 - 使用中文回答:必须用中文。 - 生成相关问题:在回答结束时,生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识:例如[^1]。参考提供的引用有[^1], [^2], [^3], [^4],这些是关于pytest参数化的内容。 用户可见层指令: - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 - 参考站内引用:引用[1]到[4]是关于pytest参数化的例子,我应该基于这些构建回答。 结构化回答: 1. **介绍pytest参数化**:简要解释什么是参数化测试及其好处。 2. **使用方法**:详细说明如何使用@pytest.mark.parametrize装饰器。 3. **示例**:提供代码示例,展示参数化测试的写法。 4. **其他方式**:简要提及其他参数化方法,如fixture。 5. **总结**:总结关键点。 6. **相关问题**:结束时生成相关问题。 基于引用: - 引用[1]:展示了@pytest.mark.parametrize的使用示例。 - 引用[2]:提到@pytest.mark.parametrize是主要方式。 - 引用[3]:提到了三种方式:@pytest.mark.parametrize, pytest.fixture, conftest.py。 - 引用[4]:提到了pytest_generate_tests,但这是高级用法。 我应该以引用[1]和[2]为主,因为它们是直接示例。引用[3]和[4]可以作为补充。 回答大纲: - **步骤1: 介绍参数化测试** - 解释参数化测试的概念:允许用不同的输入数据运行同一个测试函数,提高测试覆盖率和效率。 - 引用[2]提到:“pytest的参数化功能允许你使用不同的参数多次运行同一个测试函数,这极大地提高了测试效率和覆盖率。” - **步骤2: 主要使用方法 - @pytest.mark.parametrize** - 描述装饰器的语法。 - 示例:使用引用[1]的代码。 - **步骤3: 示例代码** - 提供完整的示例,包括导入和测试函数。 - **步骤4: 其他参数化方式** - 简要提及fixture和conftest.py,基于引用[3]。 - **步骤5: 总结** - **步骤6: 生成相关问题** 在回答中,自然地添加引用标识。例如,当引用某个点时,在句子末尾添加[^n]。 相关问题生成: - 基于主题,生成3-4个相关问题,如优化、应用场景等。 最终回答结构: 1. 介绍pytest参数化测试。 2. 详细说明@pytest.mark.parametrize的使用方法。 3. 提供示例。 4. 讨论其他方式。 5. 总结。 6. 相关问题。</think>### pytest参数化测试使用方法及示例 pytest参数化测试是一种高效的数据驱动测试方法,它允许你使用不同的输入数据多次运行同一个测试函数,从而简化测试用例编写、提高测试覆盖率和代码复用率[^2]。参数化特别适合测试函数在不同输入下的行为,如边界值测试、等价类划分等。下面我将逐步介绍使用方法,并提供详细示例。 #### 1. **核心方法:使用`@pytest.mark.parametrize`装饰器** - **作用**:通过装饰器为测试函数动态注入多组参数。 - **语法**: ```python @pytest.mark.parametrize("参数名1, 参数名2, ...", [ (值1, 值2, ...), (值3, 值4, ...), ... ]) def test_函数名(参数名1, 参数名2, ...): # 测试逻辑 ``` - **参数名**:字符串形式,定义测试函数的参数名称(如`"input, expected"`)。 - **参数值列表**:一个元组列表,每个元组对应一组测试数据。 - **可选参数**:`ids`用于为每组数据添加描述性标签(如`id="case1"`),便于调试。 - **优点**:代码简洁,易于维护,pytest会自动为每组数据生成独立的测试报告。 #### 2. **详细示例:测试乘法函数** 以下是一个完整的参数化测试示例,基于引用[1]的代码,但扩展为更完整的场景: ```python import pytest # 定义测试函数,使用参数化装饰器 @pytest.mark.parametrize( "input, expected", # 参数名称 [ (2, 4), # 第一组数据:input=2, expected=4 (3, 9), # 第二组数据 (5, 25), # 第三组数据 pytest.param(0, 0, id="边界值_0"), # 使用pytest.param添加自定义ID pytest.param(-1, 1, id="负数输入") # 支持负数和边界情况 ], ids=["正整数_2", "正整数_3", "正整数_5", "零输入", "负数输入"] # 可选:为每组数据添加描述 ) def test_multiply(input, expected): assert input * input == expected # 测试逻辑:验证平方结果 ``` - **运行结果**:pytest会生成5个独立测试用例: - 输入`2`时,预期输出`4`(标签"正整数_2")。 - 输入`3`时,预期输出`9`(标签"正整数_3")。 - ...以此类推,失败时报告会精确到具体数据组。 - **关键点**: - 每组数据独立执行,互不影响。 - 使用`pytest.param`可以添加元数据(如`id`),便于识别测试场景[^1]。 - 参数化支持任何数据类型(字符串、列表、对象等)。 #### 3. **其他参数化方式** 除了`@pytest.mark.parametrize`,pytest还提供其他方法,适用于不同场景: - **使用`pytest.fixture`参数化**: - 适合共享测试数据或预处理逻辑(如数据库连接)。 - 示例: ```python import pytest @pytest.fixture(params=[2, 3, 5]) def input_data(request): return request.param # 返回每组参数 def test_square(input_data): assert input_data * input_data == input_data ** 2 ``` - 优势:fixture可复用,适合模块化测试[^3]。 - **通过`conftest.py`全局参数化**: - 将fixture定义在`conftest.py`文件中,作用于整个测试目录。 - 示例(`conftest.py`): ```python import pytest @pytest.fixture(params=["apple", "banana"]) def fruit(request): return request.param ``` - 然后在测试文件中直接使用`fruit` fixture。 - **高级方法:`pytest_generate_tests`**: - 允许动态生成参数(如从文件或API读取数据),适合复杂场景[^4]。 - 示例: ```python def pytest_generate_tests(metafunc): if "input" in metafunc.fixturenames: metafunc.parametrize("input", [1, 2, 3]) # 动态生成参数 ``` #### 4. **最佳实践与注意事项** - **场景选择**: - 简单数据驱动:优先用`@pytest.mark.parametrize`。 - 共享资源:用fixture或`conftest.py`[^3]。 - **常见错误**: - 参数名不匹配:确保装饰器中的参数名与测试函数一致。 - 数据过多:避免超长列表,可拆分到外部文件(如CSV)。 - **效率提升**:参数化减少重复代码,但需确保每组测试独立,避免依赖状态。 参数化测试是pytest的核心功能,能显著提升测试效率。例如,在引用[1]的乘法测试中,参数化将多个用例合并为一个函数,减少了90%的冗余代码[^1]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值