pytest之测试用例参数化

本文详细介绍pytest框架中的测试用例参数化方法,包括单参数及多参数的参数化应用,通过实例展示如何有效覆盖多种测试场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

本文总结pytest的测试用例参数化。

说明

软件测试中,输入相应值,检查期望值,是常见测试方法。
在自动化测试中,一个测试用例对应一个测试点,通常一组测试数据无法完全覆盖测试范围,所以,需要参数化来传递多组数据。
pytest的测试用例参数化使用如下装饰器即可完成。

@pytest.mark.parametrize(argnames, argvalues)
# 参数:
# argnames:以逗号分隔的字符串
# argvaluse: 参数值列表,若有多个参数,一组参数以元组形式存在,包含多组参数的所有参数
# 以元组列表形式存在

示例:
参数化之一个参数。

# ./test_case/test_func.py
import pytest

@pytest.mark.parametrize("arg_1", [4399, 2012])
def test_add_by_func_aaa(arg_1):
	print(arg_1)
	
# ./run_test.py
import pytest

if __name__ == '__main__':
	pytest.main(['-v','-s'])
	
'''
============================= test session starts =============================
platform win32 -- Python 3.7.0, pytest-5.3.4, py-1.8.1, pluggy-0.13.1 -- D:\Python3.7\python.exe
cachedir: .pytest_cache
rootdir: D:\Python3.7\project\pytest, inifile: pytest.ini
plugins: allure-pytest-2.8.9, rerunfailures-8.0
collecting ... collected 2 items

test_case/test_func.py::test_add_by_func_aaa[4399] 4399
PASSED
test_case/test_func.py::test_add_by_func_aaa[2012] 2012
PASSED

============================== 2 passed in 0.04s ==============================
[Finished in 1.3s]
'''	
	

参数化之多个参数。

# ./test_case/test_func.py
import pytest		

@pytest.mark.parametrize("arg_1, arg_2", [(4399, 'AAAA'), (2012, 'BBBB')])
def test_add_by_func_aaa(arg_1,arg_2):
	print("arg_1:{}  arg_2:{}".format(arg_1, arg_2))

# ./run_test.py
import pytest

if __name__ == '__main__':
	pytest.main(['-v','-s'])
	
'''
============================= test session starts =============================
platform win32 -- Python 3.7.0, pytest-5.3.4, py-1.8.1, pluggy-0.13.1 -- D:\Python3.7\python.exe
cachedir: .pytest_cache
rootdir: D:\Python3.7\project\pytest, inifile: pytest.ini
plugins: allure-pytest-2.8.9, rerunfailures-8.0
collecting ... collected 2 items

test_case/test_func.py::test_add_by_func_aaa[4399-AAAA] arg_1:4399  arg_2:AAAA
PASSED
test_case/test_func.py::test_add_by_func_aaa[2012-BBBB] arg_1:2012  arg_2:BBBB
PASSED

============================== 2 passed in 0.05s ==============================
[Finished in 1.3s]
'''		

以上第2个示例,展现的是一个测试用例有两个参数,然后参数化了两组数据。
但在实际测试中,有的场景,比如多条件查询,比如有2个查询条件,每个条件有3个选项,如果要全部覆盖,则是3*3==9种情况。这种情景,人工测试一般是不会全部覆盖的,但在自动化测试中,只要你想,就可以做到。如下示例:
如下格式参数化,其测试结果为所有参数选项数量的乘积。

# ./test_case/test_func.py
import pytest
from func import *

'''
class TestFunc:

	# 正常测试用例
	def test_add_by_class(self):
		assert add(2,3) == 5


	def test_add_by_class_11(self):
		assert add(2,3) == 5
'''		

@pytest.mark.parametrize("arg_1", [4399,  2012, 1997])
@pytest.mark.parametrize("arg_2", ['AAAA', 'BBBB', 'CCCC'])
def test_add_by_func_aaa(arg_1,arg_2):
	print("arg_1:{}  arg_2:{}".format(arg_1, arg_2))
	

# ./run_test.py
import pytest

if __name__ == '__main__':
	pytest.main(['-v','-s'])
		
	
'''
============================= test session starts =============================
platform win32 -- Python 3.7.0, pytest-5.3.4, py-1.8.1, pluggy-0.13.1 -- D:\Python3.7\python.exe
cachedir: .pytest_cache
rootdir: D:\Python3.7\project\pytest, inifile: pytest.ini
plugins: allure-pytest-2.8.9, rerunfailures-8.0
collecting ... collected 9 items

test_case/test_func.py::test_add_by_func_aaa[AAAA-4399] arg_1:4399  arg_2:AAAA
PASSED
test_case/test_func.py::test_add_by_func_aaa[AAAA-2012] arg_1:2012  arg_2:AAAA
PASSED
test_case/test_func.py::test_add_by_func_aaa[AAAA-1997] arg_1:1997  arg_2:AAAA
PASSED
test_case/test_func.py::test_add_by_func_aaa[BBBB-4399] arg_1:4399  arg_2:BBBB
PASSED
test_case/test_func.py::test_add_by_func_aaa[BBBB-2012] arg_1:2012  arg_2:BBBB
PASSED
test_case/test_func.py::test_add_by_func_aaa[BBBB-1997] arg_1:1997  arg_2:BBBB
PASSED
test_case/test_func.py::test_add_by_func_aaa[CCCC-4399] arg_1:4399  arg_2:CCCC
PASSED
test_case/test_func.py::test_add_by_func_aaa[CCCC-2012] arg_1:2012  arg_2:CCCC
PASSED
test_case/test_func.py::test_add_by_func_aaa[CCCC-1997] arg_1:1997  arg_2:CCCC
PASSED

============================== 9 passed in 0.06s ==============================
[Finished in 1.4s]
'''
	


总结

以上,就是我们测试中使用的pytest测试用例参数化。
当然,如实际需要,你也可以把测试数据独立到文件里。然后读取出来,传递给@pytest.mark.parametrize(argnames, argvalues)装饰器。

### 如何使用 Pytest 编写测试用例 #### 使用 `pytest` 组织自动化测试用例结构 Pytest 框架能够方便地组织测试用例,在默认配置下,pytest 会自动识别以 `test_` 开头的文件以及其中定义的方法作为测试用例。这意味着只要遵循命名约定,无需额外配置即可轻松创建并运行多个测试用例如,考虑如下 Python 测试模块: ```python # 文件名为 test_feature01.py def setup_module(module): """Setup any state specific to the execution of the given module.""" pass def teardown_module(module): """Teardown any state that was previously setup with a call to setup_module.""" pass def test_case001(): assert True, "This is an example assertion" def test_case002(): value = some_function_to_test() expected_value = 'expected result' assert value == expected_value, f"Expected {expected_value}, but got {value}" def test_case00n(): # 更多测试逻辑... pass ``` 上述代码展示了如何在一个单独的 `.py` 文件中定义若干个独立的测试函数[^2]。 #### 接口功能测试用例的重要性 在着手编写具体的 pytest 测试脚本前,建议先准备好详细的接口功能测试用例文档。这一步骤对于确保后续开发工作的有效性和准确性至关重要。良好的前期规划有助于明确哪些方面需要验证,并指导具体实现细节的设计[^3]。 #### 利用 YAML 配置复杂场景下的测试数据 为了使测试更加灵活且易于维护,可以采用外部化的方式存储测试输入参数和其他依赖项。特别是当面对大量不同条件组合时,利用 YAML 或 JSON 等格式来描述这些变量变得尤为有用。通过读取此类配置文件中的内容来进行动态构建测试实,不仅简化了源码本身,也增强了其适应变化的能力。 比如,可以通过加载来自不同 YML 文件的数据集来驱动同一组核心业务逻辑的不同变体版本: ```yaml # users.yml users: - name: Alice role: admin - name: Bob role: user ``` 接着可以在测试类里解析此文件并将相应记录传递给待测对象进行交互操作[^4]。 #### 最佳实践总结 - **保持简洁明了**:尽量让单个测试尽可能短小精悍,专注于单一职责。 - **合理分层架构**:按照特性或组件划分不同的子目录存放各自的测试套件。 - **善用 fixture 功能**:借助于 pytest 提供的强大 fixtures 工具设置前置/后置动作,减少重复劳动。 - **持续集成支持**:配合 CI 平台定期触发全量回归跑批作业,及时发现潜在缺陷。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值