跳转到内容

搜索仅适用于生产版本。 尝试构建并预览网站以在本地测试。

Pytest 学习笔记

在进行接口自动化测试时,Pytest 是一个非常成熟且易于上手的单元测试框架。相比于 unittest,Pytest 更加灵活,功能更加强大。

Pytest 是一个用于编写和运行测试用例的开源框架,支持简单灵活的测试编写方式,能够与多种工具和库集成,如 requestsSelenium 等,适用于接口自动化、Web 自动化、APP 自动化测试等。

Pytest 可以与 requests 结合,用于发起接口请求;也可以与 Selenium 集成,实现 Web 自动化测试。此外,还支持 APP 自动化测试。

Pytest 提供了简单的方式来实现测试用例的跳过失败重跑机制,这在 unittest 中相对复杂。

通过与 Allure 等工具结合,Pytest 可以生成美观且易于分析的测试报告,方便结果展示和问题定位。

Pytest 可以与 Jenkins 等持续集成工具集成,实现自动化的测试和部署流程。

Pytest 拥有大量的插件,可以扩展其功能,如 pytest-htmlpytest-xdistpytest-rerunfailures 等。

  • 作用:生成 HTML 格式的测试报告。
  • 作用:实现测试用例的分布式执行,支持多进程并发,提高测试效率。
  • 作用:控制测试用例的执行顺序。
  • 作用:在测试用例失败后自动重跑,适用于临时性失败的用例。
  • 作用:与 Allure 集成,生成美观的测试报告。

使用 pip 安装所需的插件,例如:

Terminal window
pip install pytest-xdist

提示:如果安装速度较慢,可以使用国内的镜像源。


在使用 Pytest 进行测试之前,需要了解测试用例的编写规则和运行方式。

  1. 模块名称:测试模块(Python 文件)必须以 test_ 开头或以 _test 结尾。例如:
  • test_login.py

  • login_test.py

  1. 测试类:测试类必须以 Test 开头,且不能包含 __init__ 方法。例如:
class TestLogin:
pass
  1. 测试方法:测试方法必须以 test_ 开头。例如:
def test_case01(self):
pass

Pytest 提供了多种运行测试用例的方式:

在代码中调用 pytest.main(),并可传入参数。例如:

import pytest
if __name__ == "__main__":
pytest.main(["-vs", "./test_cases/", "--reruns", "2"])
  • 常用参数:
  • -s:显示打印输出等调试信息。

  • -v:详细模式,输出更详细的执行信息。

  • -n:指定并发的线程数,需要安装 pytest-xdist 插件。

  • --reruns:指定失败重跑次数,需要安装 pytest-rerunfailures 插件。

直接在命令行中使用 pytest 命令运行测试用例。例如:

pytest -vs ./test_cases/ --reruns 2

在项目根目录下创建 pytest.ini 配置文件,定义测试运行的配置。例如:

[pytest]
testpaths = ./test_cases
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts = -vs --reruns 2

注意

  • 文件名必须为 pytest.ini
  • 文件编码格式应为 UTF-8,避免使用中文字符导致报错。

可以通过命令行参数指定运行的测试模块或目录:

  • 指定模块运行
pytest ./test_cases/test_login.py
  • 指定目录运行
pytest ./test_cases/

安装 pytest-xdist 插件,实现测试用例的多进程并发执行:

pip install pytest-xdist
  • 使用方法
  • 命令行:
pytest -vs ./test_cases/ -n 3
  • 代码中:
if __name__ == "__main__":
pytest.main(["-vs", "./test_cases/", "-n", "3"])

安装 pytest-ordering 插件,使用装饰器控制执行顺序:

pip install pytest-ordering
  • 示例
import pytest
@pytest.mark.run(order=1)
def test_case1():
pass
@pytest.mark.run(order=2)
def test_case2():
pass
@pytest.mark.run(order=3)
def test_case3():
pass

安装 pytest-rerunfailures 插件,实现失败后自动重跑:

pip install pytest-rerunfailures
  • 使用方法
  • 命令行:
pytest -vs ./test_cases/ --reruns 2
  • 代码中:
if __name__ == "__main__":
pytest.main(["-vs", "./test_cases/", "--reruns", "2"])

安装 allure-pytest 插件,与 Allure 结合生成测试报告:

pip install allure-pytest
  • 使用方法
pytest -vs ./test_cases/ --alluredir ./report
  • 生成并查看报告
allure serve ./report

在实际测试中,可能需要对测试用例进行分组、跳过某些测试或有选择地执行特定的测试用例。

为什么要分组和分模块执行测试用例?

Section titled “为什么要分组和分模块执行测试用例?”

在大型项目中,测试用例数量众多,分组可以方便地管理和执行特定的测试用例,如冒烟测试、功能模块测试等。通过分组,可以提高测试效率,节省时间。

使用 @pytest.mark.<marker_name> 装饰器为测试用例添加自定义标记。例如:

import pytest
@pytest.mark.smoke
def test_login_success():
pass
@pytest.mark.user_management
def test_add_user():
pass
@pytest.mark.user_management
def test_delete_user():
pass

为避免警告,需要在 pytest.ini 中注册自定义标记:

[pytest]
markers =
smoke: 冒烟测试用例
user_management: 用户管理模块测试用例

使用 -m 参数指定运行特定标记的测试用例:

  • 执行所有冒烟测试用例
pytest -m smoke
  • 执行用户管理模块的测试用例
pytest -m user_management
  • 组合标记执行
  • 同时执行冒烟测试和用户管理模块的测试用例:
pytest -m "smoke or user_management"
  • 仅执行同时属于冒烟测试和用户管理模块的测试用例:
pytest -m "smoke and user_management"
  • 标记名称需保持一致:标记名称需要在装饰器、配置文件和命令行中保持一致。

  • 导入 pytest 模块:在使用 @pytest.mark 时,需要先 import pytest

  • 逻辑运算符:在命令行中使用逻辑运算符(andornot)组合标记时,需要用引号括起来。

使用 @pytest.mark.skip 无条件跳过测试

Section titled “使用 @pytest.mark.skip 无条件跳过测试”

当某个测试用例暂时不需要执行时,可以使用 @pytest.mark.skip 装饰器:

import pytest
@pytest.mark.skip(reason="功能未实现")
def test_feature_x():
pass
  • 解释reason 参数用于说明跳过的原因。

使用 @pytest.mark.skipif 有条件跳过测试

Section titled “使用 @pytest.mark.skipif 有条件跳过测试”

根据条件决定是否跳过测试,用 @pytest.mark.skipif 装饰器:

import pytest
import sys
@pytest.mark.skipif(sys.platform == "win32", reason="不支持 Windows 平台")
def test_unix_only_feature():
pass
  • 解释:当条件为 True 时,测试将被跳过。

在测试函数内部,根据运行时条件跳过测试:

import pytest
def test_dynamic_skip():
if not is_feature_available():
pytest.skip("该功能不可用")
pass
  • 解释:当跳过决策依赖于运行时信息时,这种方式非常有用。
  • 一致的标记命名:使用清晰、统一的标记名称,使测试选择更直观。

  • 标记文档化:在 pytest.ini 中注册标记,避免警告并便于维护。

  • 合理使用条件:在使用 skipif 时,条件应准确反映跳过的场景。

  • 组合标记:利用标记组合,实现灵活的测试执行,适应不同的测试需求。

  • 定期检查跳过的测试:避免长期跳过测试掩盖潜在问题,定期检查并更新。

在进行接口自动化测试时,Pytest 是一个非常成熟且易于上手的单元测试框架。相比于 unittest,Pytest 更加灵活,功能更加强大。

Pytest 是一个用于编写和运行测试用例的开源框架,支持简单灵活的测试编写方式,能够与多种工具和库集成,如 requestsSelenium 等,适用于接口自动化、Web 自动化、APP 自动化测试等。

Pytest 可以与 requests 结合,用于发起接口请求;也可以与 Selenium 集成,实现 Web 自动化测试。此外,还支持 APP 自动化测试。

Pytest 提供了简单的方式来实现测试用例的跳过失败重跑机制,这在 unittest 中相对复杂。

通过与 Allure 等工具结合,Pytest 可以生成美观且易于分析的测试报告,方便结果展示和问题定位。

Pytest 可以与 Jenkins 等持续集成工具集成,实现自动化的测试和部署流程。

Pytest 拥有大量的插件,可以扩展其功能,如 pytest-htmlpytest-xdistpytest-rerunfailures 等。

  • 作用:生成 HTML 格式的测试报告。
  • 作用:实现测试用例的分布式执行,支持多进程并发,提高测试效率。
  • 作用:控制测试用例的执行顺序。
  • 作用:在测试用例失败后自动重跑,适用于临时性失败的用例。
  • 作用:与 Allure 集成,生成美观的测试报告。

使用 pip 安装所需的插件,例如:

Terminal window
pip install pytest-xdist

提示:如果安装速度较慢,可以使用国内的镜像源。


在使用 Pytest 进行测试之前,需要了解测试用例的编写规则和运行方式。

  1. 模块名称:测试模块(Python 文件)必须以 test_ 开头或以 _test 结尾。例如:
  • test_login.py

  • login_test.py

  1. 测试类:测试类必须以 Test 开头,且不能包含 __init__ 方法。例如:
class TestLogin:
pass
  1. 测试方法:测试方法必须以 test_ 开头。例如:
def test_case01(self):
pass

Pytest 提供了多种运行测试用例的方式:

在代码中调用 pytest.main(),并可传入参数。例如:

import pytest
if __name__ == "__main__":
pytest.main(["-vs", "./test_cases/", "--reruns", "2"])
  • 常用参数:
  • -s:显示打印输出等调试信息。

  • -v:详细模式,输出更详细的执行信息。

  • -n:指定并发的线程数,需要安装 pytest-xdist 插件。

  • --reruns:指定失败重跑次数,需要安装 pytest-rerunfailures 插件。

直接在命令行中使用 pytest 命令运行测试用例。例如:

pytest -vs ./test_cases/ --reruns 2

在项目根目录下创建 pytest.ini 配置文件,定义测试运行的配置。例如:

[pytest]
testpaths = ./test_cases
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts = -vs --reruns 2

注意

  • 文件名必须为 pytest.ini
  • 文件编码格式应为 UTF-8,避免使用中文字符导致报错。

可以通过命令行参数指定运行的测试模块或目录:

  • 指定模块运行
pytest ./test_cases/test_login.py
  • 指定目录运行
pytest ./test_cases/

安装 pytest-xdist 插件,实现测试用例的多进程并发执行:

pip install pytest-xdist
  • 使用方法
  • 命令行:
pytest -vs ./test_cases/ -n 3
  • 代码中:
if __name__ == "__main__":
pytest.main(["-vs", "./test_cases/", "-n", "3"])

安装 pytest-ordering 插件,使用装饰器控制执行顺序:

pip install pytest-ordering
  • 示例
import pytest
@pytest.mark.run(order=1)
def test_case1():
pass
@pytest.mark.run(order=2)
def test_case2():
pass
@pytest.mark.run(order=3)
def test_case3():
pass

安装 pytest-rerunfailures 插件,实现失败后自动重跑:

pip install pytest-rerunfailures
  • 使用方法
  • 命令行:
pytest -vs ./test_cases/ --reruns 2
  • 代码中:
if __name__ == "__main__":
pytest.main(["-vs", "./test_cases/", "--reruns", "2"])

安装 allure-pytest 插件,与 Allure 结合生成测试报告:

pip install allure-pytest
  • 使用方法
pytest -vs ./test_cases/ --alluredir ./report
  • 生成并查看报告
allure serve ./report

在实际测试中,可能需要对测试用例进行分组、跳过某些测试或有选择地执行特定的测试用例。

为什么要分组和分模块执行测试用例?

Section titled “为什么要分组和分模块执行测试用例?”

在大型项目中,测试用例数量众多,分组可以方便地管理和执行特定的测试用例,如冒烟测试、功能模块测试等。通过分组,可以提高测试效率,节省时间。

使用 @pytest.mark.<marker_name> 装饰器为测试用例添加自定义标记。例如:

import pytest
@pytest.mark.smoke
def test_login_success():
pass
@pytest.mark.user_management
def test_add_user():
pass
@pytest.mark.user_management
def test_delete_user():
pass

为避免警告,需要在 pytest.ini 中注册自定义标记:

[pytest]
markers =
smoke: 冒烟测试用例
user_management: 用户管理模块测试用例

使用 -m 参数指定运行特定标记的测试用例:

  • 执行所有冒烟测试用例
pytest -m smoke
  • 执行用户管理模块的测试用例
pytest -m user_management
  • 组合标记执行
  • 同时执行冒烟测试和用户管理模块的测试用例:
pytest -m "smoke or user_management"
  • 仅执行同时属于冒烟测试和用户管理模块的测试用例:
pytest -m "smoke and user_management"
  • 标记名称需保持一致:标记名称需要在装饰器、配置文件和命令行中保持一致。

  • 导入 pytest 模块:在使用 @pytest.mark 时,需要先 import pytest

  • 逻辑运算符:在命令行中使用逻辑运算符(andornot)组合标记时,需要用引号括起来。

使用 @pytest.mark.skip 无条件跳过测试

Section titled “使用 @pytest.mark.skip 无条件跳过测试”

当某个测试用例暂时不需要执行时,可以使用 @pytest.mark.skip 装饰器:

import pytest
@pytest.mark.skip(reason="功能未实现")
def test_feature_x():
pass
  • 解释reason 参数用于说明跳过的原因。

使用 @pytest.mark.skipif 有条件跳过测试

Section titled “使用 @pytest.mark.skipif 有条件跳过测试”

根据条件决定是否跳过测试,用 @pytest.mark.skipif 装饰器:

import pytest
import sys
@pytest.mark.skipif(sys.platform == "win32", reason="不支持 Windows 平台")
def test_unix_only_feature():
pass
  • 解释:当条件为 True 时,测试将被跳过。

在测试函数内部,根据运行时条件跳过测试:

import pytest
def test_dynamic_skip():
if not is_feature_available():
pytest.skip("该功能不可用")
pass
  • 解释:当跳过决策依赖于运行时信息时,这种方式非常有用。
  • 一致的标记命名:使用清晰、统一的标记名称,使测试选择更直观。

  • 标记文档化:在 pytest.ini 中注册标记,避免警告并便于维护。

  • 合理使用条件:在使用 skipif 时,条件应准确反映跳过的场景。

  • 组合标记:利用标记组合,实现灵活的测试执行,适应不同的测试需求。

  • 定期检查跳过的测试:避免长期跳过测试掩盖潜在问题,定期检查并更新。