pytest 基础用法教程

文章目录

      • [1. 文件及用例命名规范](#1. 文件及用例命名规范)
      • [2. 常用的断言类型](#2. 常用的断言类型)
      • [3. 指定目录与文件执行用例](#3. 指定目录与文件执行用例)
      • [4. 运行参数 `-m` 和 `-k`](#4. 运行参数 -m-k)
      • [5. 使用 `pytest.ini` 配置文件](#5. 使用 pytest.ini 配置文件)
      • [6. setup 和 teardown 详解](#6. setup 和 teardown 详解)
      • [7. 测试用例执行顺序](#7. 测试用例执行顺序)
      • [8. skip 和 skipif:测试用例跳过](#8. skip 和 skipif:测试用例跳过)
      • [9. 解决接口参数依赖 (结合 pytest + requests 练习)](#9. 解决接口参数依赖 (结合 pytest + requests 练习))

1. 文件及用例命名规范

pytest 默认会有一套自动发现测试用例的规则。只有符合规则的文件和函数,才会被执行。

  • 测试文件 :必须以 test_*.py 开头或 *_test.py 结尾。
  • 测试类 :必须以 Test 开头,且不能包含 __init__ 方法。
  • 测试函数/方法 :必须以 test_ 开头。

2. 常用的断言类型

与 Python 自带的 unittest 需要使用 assertEqualassertTrue 不同,pytest 直接使用 Python 原生的 assert 关键字即可。

python 复制代码
def test_assertions():
    assert 1 + 1 == 2        # 判断相等
    assert "test" in "pytest" # 判断包含
    assert 3 > 2             # 判断大小
    assert True              # 判断真假

3. 指定目录与文件执行用例

在命令行中,你可以灵活指定要运行的测试范围:

  • 运行所有用例 :在项目根目录下直接输入 pytest
  • 运行指定目录pytest tests/ (运行 tests 文件夹下的所有用例)
  • 运行指定文件pytest test_api.py
  • 运行指定函数pytest test_api.py::test_login

4. 运行参数 -m-k

这两个参数用于在海量用例中过滤出你想执行的用例。

  • -k (关键字匹配) :运行名称中包含指定字符串的用例。

    bash 复制代码
    pytest -k "login or register"  # 运行名字中包含 login 或 register 的用例
  • -m (标记匹配) :运行带有特定自定义标记(如 @pytest.mark.smoke)的用例。

    bash 复制代码
    pytest -m "smoke" # 运行被打上 smoke 标签的冒烟测试用例

5. 使用 pytest.ini 配置文件

为了避免每次都在命令行输入一长串参数,可以将配置写在项目根目录的 pytest.ini 文件中。

ini 复制代码
[pytest]
# 配置默认运行参数 (例如:-v 打印详细信息, -s 打印控制台输出)
addopts = -v -s -m "smoke"

# 配置 pytest 寻找用例的默认目录 (testpaths)
testpaths = ./tests

# 注册自定义标记,消除警告
markers =
    smoke: 冒烟测试
    api: 接口测试

6. setup 和 teardown 详解

用于在测试执行前进行环境初始化(如建立数据库连接),测试后进行环境清理(如清除脏数据)。pytest 支持多个级别的 setup/teardown:

  • 模块级 (Module)setup_module() / teardown_module(),在整个 .py 文件前后执行一次。
  • 类级 (Class)setup_class() / teardown_class(),在整个测试类前后执行一次。
  • 方法/函数级 (Method/Function)setup_method() / teardown_method(),在每个用例前后都会执行。
python 复制代码
import pytest

# ================= 1. 模块级 (Module Level) =================
# 针对整个 .py 文件,在所有用例开始前和结束后各运行一次
def setup_module():
    print("\n【模块级】setup_module:整个文件开始执行。(例如:建立全局数据库连接)")

def teardown_module():
    print("\n【模块级】teardown_module:整个文件执行完毕。(例如:断开全局数据库连接)")


# ================= 2. 函数级 (Function Level) =================
# 针对类外部的测试函数,在每个测试函数前后都会运行
def setup_function():
    print("\n  [函数级] setup_function:准备执行类外部的测试函数。(例如:准备测试数据)")

def teardown_function():
    print("  [函数级] teardown_function:类外部的测试函数执行完毕。(例如:清理测试数据)")

def test_outside_func_1():
    print("    -> 正在执行测试函数: test_outside_func_1")
    assert 1 + 1 == 2

def test_outside_func_2():
    print("    -> 正在执行测试函数: test_outside_func_2")
    assert True


# ================= 3. 类级 & 方法级 (Class & Method Level) =================
class TestUserLogin:
    
    # 针对整个类,在类的第一个用例前和最后一个用例后运行一次
    def setup_class(self):
        print("\n  【类级】setup_class:TestUserLogin 类开始执行。(例如:启动浏览器/创建测试用户)")

    def teardown_class(self):
        print("\n  【类级】teardown_class:TestUserLogin 类执行完毕。(例如:关闭浏览器/删除测试用户)")

    # 针对类里面的每一个测试方法,在每个方法前后都会运行
    def setup_method(self):
        print("\n    [方法级] setup_method:准备执行类中的测试方法。(例如:打开登录页面)")

    def teardown_method(self):
        print("    [方法级] teardown_method:类中的测试方法执行完毕。(例如:清除浏览器 Cookie)")

    def test_login_success(self):
        print("      -> 正在执行测试方法: test_login_success")
        assert "login" in "login_success"

    def test_login_fail(self):
        print("      -> 正在执行测试方法: test_login_fail")
        assert 3 > 2

7. 测试用例执行顺序

  • 默认顺序:pytest 默认按照代码在文件中从上到下的顺序执行。

  • 自定义顺序 :可以通过安装 pytest-ordering 插件,并使用装饰器来改变顺序:

    python 复制代码
    import pytest
    
    @pytest.mark.run(order=2)
    def test_two():
        pass
    
    @pytest.mark.run(order=1)
    def test_one():
        pass

8. skip 和 skipif:测试用例跳过

有时某些用例还没写完,或者在特定环境下不需要运行,可以跳过它们。

python 复制代码
import pytest
import sys

# 无条件跳过
@pytest.mark.skip(reason="接口还在开发中,暂不执行")
def test_unfinished_api():
    pass

# 有条件跳过 (例如:如果不是 Windows 系统则跳过)
@pytest.mark.skipif(sys.platform != "win32", reason="仅在 Windows 下运行")
def test_windows_feature():
    pass

9. 解决接口参数依赖 (结合 pytest + requests 练习)

在编写 requests 接口自动化测试时,经常遇到接口依赖 的问题。比如:"获取用户信息"接口,依赖"登录"接口返回的 Token

在 pytest 中,解决这类数据传递的最佳实践是使用 Fixture (夹具),它比传统的 setup 更灵活。

python 复制代码
import pytest
import requests

# 1. 定义一个 fixture,用于模拟登录获取 Token
@pytest.fixture()
def get_token():
    # 实际场景下这里会是一个 requests.post() 登录请求
    # response = requests.post("http://api.example.com/login", json={"user": "admin", "pwd": "123"})
    # token = response.json().get("token")
    
    print("\n--- 正在调用登录接口提取 Token ---")
    token = "eyJhbGciOiJIUzI1NiIsInR5cCI..." # 模拟提取到的 Token
    return token

# 2. 在需要依赖的测试用例中,直接将 fixture 的名字作为参数传入
def test_get_user_info(get_token):
    # get_token 变量现在包含了上面 fixture 返回的值
    headers = {"Authorization": f"Bearer {get_token}"}
    
    # 携带 token 发起下一个请求
    # response = requests.get("http://api.example.com/user_info", headers=headers)
    # assert response.status_code == 200
    
    print(f"\n使用 Token 请求用户信息: {headers}")
    assert get_token is not None

相关推荐
我的xiaodoujiao1 天前
3、API 接口自动化测试详细图文教程学习系列3--相关Python基础知识2
python·学习·测试工具·pytest
小陈的进阶之路1 天前
Pytest 框架与 Fixture 总结
笔记·pytest
我的xiaodoujiao1 天前
4、API 接口自动化测试详细图文教程学习系列4--相关Python基础知识3
python·学习·测试工具·pytest
小罗和阿泽1 天前
接口测试系列 接口自动化测试 pytest框架(三)
开发语言·python·pytest
独断万古他化2 天前
Python+Pytest 接口自动化测试实战 —— 抽奖系统接口测试框架设计与实现
python·pytest·接口自动化·测试·allure·yaml·json schema
小陈的进阶之路2 天前
Selenium 常用操作 API
python·自动化·pytest
紫丁香2 天前
pytest_自动化测试5
python·功能测试·单元测试·集成测试·pytest
姚青&2 天前
Pytest fixture 参数化(params 参数)
开发语言·python·pytest