1. 项目概述与核心价值

最近在带团队做项目重构,其中一个核心任务就是把之前零散、手工执行的接口测试给自动化、体系化。我们选型了 Python + Requests + PyTest + Excel + Allure 这套组合拳。这套方案听起来组件不少,但组合起来用,你会发现它既轻量又强大,特别适合从零开始搭建或者对现有测试流程进行优化。它不是那种大而全、学习成本巨高的企业级框架,而是把几个各自领域最优秀的“单功能”工具,用清晰的逻辑串联起来,形成一个高效、可维护的自动化测试工程。

简单来说, Requests 负责最基础的 HTTP 通信, PyTest 作为测试组织和执行的大脑, Excel (或 CSV)充当直观易懂的测试数据仓库,而 Allure 则负责生成那份让人一看就懂、能直接拿去给领导或产品看的精美测试报告。这套组合解决了几个关键痛点:测试用例与代码分离便于非技术人员维护、测试执行灵活高效、测试结果可视化程度高。无论你是测试开发新手,还是想优化团队测试流程的负责人,这套实战方案都能给你提供一个清晰、可落地的路径。接下来,我就把这套方案的搭建思路、核心细节、踩过的坑以及如何优雅地呈现结果,毫无保留地拆解给你看。

2. 技术栈选型与架构设计思路

为什么是这五个技术点的组合?而不是 Postman + Newman,或者干脆上 Robot Framework?这里面的选型逻辑,是基于“ 核心需求驱动 ”和“ 工具边界清晰 ”两个原则。

2.1 各组件核心职责解析

  • Python : 这是基石。选择 Python 是因为它在测试领域的生态极其丰富,语法简洁,团队学习成本低。它像胶水一样,把其他组件粘合在一起。
  • Requests : HTTP for Humans。在接口测试中,我们 99% 的时间都在和 HTTP 协议打交道。Requests 库用起来非常直观, requests.get() , requests.post() 几乎就是口语化的表达,远比 Python 内置的 urllib 友好,也足够强大到处理鉴权、会话、文件上传等各种复杂场景。它的定位就是“做好 HTTP 请求这一件事”。
  • PyTest : 测试框架的“瑞士军刀”。它不仅仅是一个 runner,更是一套完整的测试生态系统。它的 fixture 机制可以优雅地处理测试前置(如登录获取 token)、后置(清理测试数据)依赖; 参数化 功能能轻松实现数据驱动;丰富的插件体系(如 allure-pytest)让它能轻松集成报告工具。它的设计哲学是“约定优于配置”,让写测试用例像写普通函数一样自然。
  • Excel/CSV : 数据与代码分离的关键。将测试用例的输入(请求参数)和预期输出(响应校验点)放在 Excel 中,有三大好处:一是产品、运营等非技术人员可以参与用例评审和维护;二是批量修改测试数据无需改动代码;三是结构清晰,易于管理大量用例。虽然数据库也能存,但 Excel 的普适性和可视化编辑能力在项目初期优势明显。我们通常用 openpyxl pandas 来操作。
  • Allure : 测试报告的“颜值担当”。它生成的报告不仅仅是“通过/失败”的统计,更能展示测试套件的层级关系、用例步骤的详细日志、失败时的请求响应信息、甚至附件(如图片、日志文件)。这种程度的可视化,对于定位问题、汇报测试结果至关重要。Allure 是一个独立的报告工具,通过适配器(如 allure-pytest)收集 PyTest 执行过程中的信息,最后生成一个静态 HTML 报告。

2.2 整体架构设计图(逻辑层面)

整个自动化项目的代码结构,我推荐按功能模块划分,而不是按技术组件划分。一个典型的结构如下:

api_auto_framework/
├── common/           # 公共模块
│   ├── __init__.py
│   ├── logger.py     # 日志配置
│   ├── request_client.py # 封装的Requests客户端
│   └── config.py     # 配置文件(读取yaml/ini)
├── data/             # 测试数据
│   └── test_cases.xlsx # Excel数据文件
├── test_cases/       # 测试用例集
│   ├── __init__.py
│   ├── conftest.py   # pytest共享fixture
│   ├── test_login.py # 登录模块测试
│   └── test_order.py # 订单模块测试
├── reports/          # 测试报告(.gitignore)
│   ├── allure-results/ # allure原始结果
│   └── allure-report/  # 生成的html报告
├── utils/            # 工具函数
│   ├── __init__.py
│   ├── excel_reader.py # 读取Excel工具
│   └── assert_utils.py # 自定义断言工具
├── pytest.ini        # pytest配置文件
└── requirements.txt  # 项目依赖

这个结构的核心思想是“ 高内聚、低耦合 ”。 common 里的 request_client 是对 Requests 的二次封装,加入日志、通用头、异常处理等; test_cases 目录下的每个文件都是一个业务测试集,它们调用封装的客户端和读取的数据; utils 提供通用的工具方法; data 目录独立存放数据。 conftest.py 是 PyTest 的魔力所在,里面定义的 fixture 可以被该目录及其子目录下的所有测试文件使用。

注意 reports 目录一定要加入 .gitignore ,因为 allure 生成的报告是动态的,不应该纳入版本控制。

3. 核心模块实现与关键技术点

有了架构,我们来逐一实现核心模块。这是从设计图到可运行代码的关键一步。

3.1 封装健壮的 HTTP 请求客户端

直接在每个测试用例里写 requests.post(url, json=data) 是初学者的做法,不利于维护。我们需要一个统一的客户端。这个客户端至少要处理: 基础URL管理、请求头设置(尤其是动态Token)、请求日志记录、通用响应处理、异常重试

# common/request_client.py
import requests
import logging
from typing import Any, Dict, Optional
from common.logger import setup_logger

class ApiClient:
    def __init__(self, base_url: str):
        self.base_url = base_url.rstrip('/')
        self.session = requests.Session()  # 使用Session保持会话(如cookie)
        self.logger = setup_logger(__name__)

    def _request(self, method: str, endpoint: str, **kwargs) -> requests.Response:
        """统一发送请求的方法"""
        url = f"{self.base_url}{endpoint}"
        self.logger.info(f"请求开始: {method} {url}")
        self.logger.debug(f"请求参数: {kwargs.get('json', kwargs.get('data', {}))}")

        try:
            resp = self.session.request(method, url, **kwargs)
            resp.raise_for_status()  # 如果状态码不是2xx,抛出HTTPError异常
        except requests.exceptions.RequestException as e:
            self.logger.error(f"请求失败: {e}")
            raise  # 将异常抛给上层测试用例处理
        finally:
            # 无论成功失败,都记录响应概要(注意敏感信息脱敏)
            self.logger.info(f"响应状态码: {resp.status_code}")
            self.logger.debug(f"响应内容: {resp.text[:500]}")  # 只记录前500字符防止日志爆炸

        return resp

    # 提供便捷方法
    def get(self, endpoint: str, params: Optional[Dict] = None, **kwargs):
        return self._request('GET', endpoint, params=params, **kwargs)

    def post(self, endpoint: str, json: Optional[Dict] = None, **kwargs):
        return self._request('POST', endpoint, json=json, **kwargs)

    # 可以继续封装 put, delete, patch 等方法

    def set_common_headers(self, headers: Dict):
        """设置会话级别的公共请求头,如User-Agent, Content-Type"""
        self.session.headers.update(headers)

    def update_token(self, token: str):
        """更新认证Token,通常从登录fixture获取"""
        self.session.headers.update({'Authorization': f'Bearer {token}'})

关键点

  1. 使用 requests.Session() :这非常重要。Session 可以自动保持 cookies,在一次会话中(如登录后)的所有请求都会携带认证信息,模拟真实浏览器行为。
  2. 日志分级 :使用 info 记录关键步骤(如请求开始、状态码),使用 debug 记录详细数据(请求/响应体)。在生产运行时可关闭 debug 日志,避免信息过载。
  3. 异常处理 resp.raise_for_status() 能自动检查 HTTP 状态码。我们将网络请求异常抛出,由测试用例决定是标记为失败还是进行重试等操作。
  4. Token 管理 :通过 update_token 方法,我们可以在登录成功后,动态地将 token 设置到 session 的 headers 中,后续所有请求自动携带。

3.2 实现数据驱动的 Excel 读取器

测试数据放在 Excel 里,我们需要一个工具来读取它,并转换成 PyTest 参数化需要的数据格式。假设我们的 test_cases.xlsx 中有一个 Login 工作表,结构如下:

用例ID 用例描述 用户名 密码 预期状态码 预期响应消息
TC_LOGIN_001 登录成功 admin admin123 200 登录成功
TC_LOGIN_002 用户名错误 wrong admin123 401 用户名或密码错误
# utils/excel_reader.py
import pandas as pd
from typing import List, Dict, Any
import logging

logger = logging.getLogger(__name__)

class ExcelReader:
    def __init__(self, file_path: str):
        self.file_path = file_path
        # 使用pandas的ExcelFile对象,避免重复打开文件
        self.xls = pd.ExcelFile(file_path)

    def get_sheet_data(self, sheet_name: str) -> List[Dict[str, Any]]:
        """读取指定工作表的所有数据,返回字典列表"""
        try:
            df = pd.read_excel(self.xls, sheet_name=sheet_name, dtype=str)  # 全部按字符串读入,避免数字类型问题
            # 填充NaN为空字符串
            df = df.fillna('')
            # 将DataFrame转换为字典列表
            data = df.to_dict('records')
            logger.info(f"从工作表 [{sheet_name}] 成功读取 {len(data)} 条测试数据。")
            return data
        except Exception as e:
            logger.error(f"读取Excel文件 {self.file_path} 的工作表 {sheet_name} 失败: {e}")
            raise

    def get_data_for_pytest(self, sheet_name: str, filter_func=None):
        """
        为pytest参数化准备数据。
        filter_func: 可选,一个用于过滤或转换数据的函数。
        返回格式: [(data1,), (data2,)] 或 [(data1_id, data1), (data2_id, data2)]
        """
        raw_data = self.get_sheet_data(sheet_name)
        if filter_func:
            raw_data = filter_func(raw_data)

        # 为每条数据生成一个易读的ID,用于pytest参数化显示
        param_data = []
        for item in raw_data:
            # 假设每条数据都有‘用例ID’和‘用例描述’字段
            case_id = item.get('用例ID', 'N/A')
            case_desc = item.get('用例描述', 'N/A')
            # pytest参数化的id会显示在测试报告中
            param_id = f"{case_id}_{case_desc}"
            param_data.append(pytest.param(item, id=param_id))

        return param_data

关键点

  1. 使用 Pandas pandas 处理 Excel 非常强大,能轻松处理不同的数据类型、空值和工作表。
  2. 数据清洗 fillna('') 将空单元格转为空字符串,避免后续处理时出现 NaN 这种 Pandas 特有的类型,导致 JSON 序列化等问题。
  3. 适配 PyTest pytest.param() 是 PyTest 参数化的高级用法,其中的 id 参数会显示在测试报告里,让你一眼就知道是哪个数据用例失败了。
  4. 灵活性 filter_func 参数允许你在读取数据后进行二次加工,比如只运行标记为‘冒烟测试’的用例。

3.3 构建可复用的 PyTest Fixture

Fixture 是 PyTest 的灵魂,用于准备测试环境和管理测试资源。我们把 API 客户端和测试数据的准备都放在 conftest.py 里。

# test_cases/conftest.py
import pytest
from common.request_client import ApiClient
from utils.excel_reader import ExcelReader
import os

# 获取项目根目录
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DATA_FILE = os.path.join(BASE_DIR, 'data', 'test_cases.xlsx')

@pytest.fixture(scope="session")
def api_client():
    """创建全局的API客户端,整个测试会话只创建一次"""
    # 从配置文件读取基础URL,这里用环境变量示例
    base_url = os.getenv('BASE_URL', 'https://api.yourdomain.com')
    client = ApiClient(base_url)
    # 设置一些公共请求头
    client.set_common_headers({
        'Content-Type': 'application/json',
        'User-Agent': 'Pytest-Api-Test/1.0'
    })
    yield client  # 测试结束后,yield后面的代码会执行清理(如果有的话)
    # 可以在这里关闭session或做其他清理
    client.session.close()

@pytest.fixture(scope="session")
def excel_reader():
    """创建全局的Excel读取器"""
    reader = ExcelReader(DATA_FILE)
    yield reader

@pytest.fixture
def auth_client(api_client):
    """一个需要认证的客户端fixture。它依赖于api_client,并先执行登录"""
    # 这里模拟登录获取token。实际项目中,登录信息可能来自环境变量或配置。
    login_data = {"username": "test_user", "password": "test_pass"}
    resp = api_client.post("/auth/login", json=login_data)
    token = resp.json().get('data', {}).get('token')
    if token:
        api_client.update_token(token)
    else:
        pytest.fail("登录失败,无法获取Token")
    yield api_client  # 返回已携带token的客户端
    # 测试结束后,可以在这里执行登出(如果需要)
    # api_client.post("/auth/logout")

关键点

  1. Fixture 作用域 scope="session" 表示这个 fixture 在整个 pytest 执行过程中只创建一次,非常适合耗时的操作(如创建 HTTP 会话、读取大文件)。 scope="function" (默认)则是每个测试函数都运行一次。
  2. Fixture 依赖 auth_client fixture 依赖于 api_client 。PyTest 会自动处理依赖关系,先执行 api_client ,再执行 auth_client 。这实现了“模块化构建”。
  3. yield 语法 :这是做资源清理的标准模式。 yield 之前是 setup, yield 之后是 teardown。即使测试失败,teardown 部分的代码也会执行,确保环境干净。
  4. 登录逻辑 :将登录操作放在一个 fixture 中,所有需要认证的测试用例只需引用 auth_client 即可,实现了登录逻辑的复用和分离。

4. 编写与组织测试用例

有了稳固的基础设施,编写测试用例就变得非常简洁和高效。我们遵循“ 用例即数据,测试即脚本 ”的原则。

4.1 一个完整的测试用例示例

我们以登录接口为例,展示如何将 Excel 中的数据驱动与 PyTest 测试函数结合。

# test_cases/test_login.py
import pytest
import allure
from utils.assert_utils import assert_response

# 假设我们有一个自定义的、更强大的断言工具
# utils/assert_utils.py
# def assert_response(actual_resp, expected_status_code, expected_fields_mapping):
#     """校验状态码和响应体中的特定字段"""
#     assert actual_resp.status_code == expected_status_code
#     resp_json = actual_resp.json()
#     for field, expected_value in expected_fields_mapping.items():
#         # 支持嵌套字段的点号表示法,如 `data.token`
#         actual_value = _get_nested_value(resp_json, field)
#         assert actual_value == expected_value, f"字段 {field} 校验失败: {actual_value} != {expected_value}"

class TestLogin:
    """登录模块测试类"""

    @pytest.mark.parametrize("test_data", excel_reader.get_data_for_pytest("Login"))
    @allure.story("用户登录功能")
    @allure.title("登录测试 - {test_data[用例描述]}")
    def test_login(self, api_client, test_data):
        """
        数据驱动的登录测试。
        参数test_data来自Excel中‘Login’工作表的每一行。
        """
        # 1. 准备请求数据
        request_data = {
            "username": test_data["用户名"],
            "password": test_data["密码"]
        }

        # 2. 发送请求
        with allure.step(f"Step 1: 发送登录请求 (用户: {test_data['用户名']})"):
            response = api_client.post("/auth/login", json=request_data)

        # 3. 断言验证
        with allure.step("Step 2: 验证响应"):
            # 解析Excel中的预期结果。注意:Excel中数字读出来是字符串,需要转换
            expected_status_code = int(test_data["预期状态码"])
            # 预期消息可能是一个字符串,也可能是一个字典路径。这里简单处理为字符串匹配。
            expected_msg = test_data["预期响应消息"]

            # 使用自定义断言工具进行校验
            assert_response(
                response,
                expected_status_code,
                {"message": expected_msg}  # 假设响应体顶层有message字段
            )
            # 如果登录成功,还可以进一步校验返回的token或用户信息
            if expected_status_code == 200:
                with allure.step("Step 3: 验证登录成功后的返回数据"):
                    resp_json = response.json()
                    assert "data" in resp_json
                    assert "token" in resp_json["data"]
                    allure.attach(response.text, name="响应详情", attachment_type=allure.attachment_type.TEXT)

关键点

  1. @pytest.mark.parametrize :这是实现数据驱动的核心装饰器。 excel_reader.get_data_for_pytest("Login") 返回一个参数列表,PyTest 会为列表中的每个元素(即 Excel 中的每一行)单独运行一次 test_login 方法。
  2. Allure 装饰器与步骤
    • @allure.story @allure.title 用于在 Allure 报告中更好地组织测试用例。 title 支持动态参数,使得报告中的用例名称一目了然。
    • with allure.step() 上下文管理器可以将一个测试方法分解为多个步骤,在报告中清晰展示执行过程,对于调试复杂流程非常有用。
    • allure.attach() 可以在报告中附加文本、图片等额外信息。这里我们把成功的响应详情附上,方便查看。
  3. 断言策略 :不要只用 assert response.status_code == 200 。我们封装了 assert_response 工具,可以同时校验状态码和响应体中的关键字段,使断言更强大、更清晰。断言失败时,PyTest 会输出详细的差异信息。
  4. 测试类组织 :将同一模块的测试用例组织在一个类中(如 TestLogin ),逻辑更清晰,也便于使用类级别的 fixture。

4.2 测试用例的组织与标记

随着用例增多,我们需要对用例进行分类和筛选。PyTest 的 mark 机制非常好用。

# 在 conftest.py 中注册自定义标记
def pytest_configure(config):
    config.addinivalue_line(
        "markers", "smoke: 标记为冒烟测试用例"
    )
    config.addinivalue_line(
        "markers", "slow: 标记为执行较慢的用例"
    )

# 在测试用例上使用标记
class TestOrder:
    @pytest.mark.smoke
    def test_create_order_quickly(self, auth_client):
        """冒烟测试:快速创建订单"""
        pass

    @pytest.mark.slow
    def test_order_report_download(self, auth_client):
        """慢速测试:下载大型订单报表"""
        pass

运行测试时,可以只运行冒烟测试: pytest -m smoke ,或者排除慢速测试: pytest -m "not slow"

5. 测试执行、报告生成与集成

一切就绪,如何运行并得到漂亮的报告?

5.1 命令行执行与常用参数

最基础的运行命令是 pytest ,它会自动发现并运行当前目录及子目录下所有以 test_ 开头或结尾的文件。

为了生成 Allure 报告,我们需要分两步:

# 第一步:运行测试并生成Allure所需的原始结果数据(-s 显示print输出,-v 详细模式)
pytest test_cases/ -v -s --alluredir=./reports/allure-results

# 第二步:根据原始数据生成HTML报告
allure generate ./reports/allure-results -o ./reports/allure-report --clean
# 打开报告
allure open ./reports/allure-report

常用 PyTest 参数

  • -k KEYWORD : 按名称过滤测试用例,如 pytest -k "login"
  • -x : 遇到第一个失败用例就停止。
  • --maxfail=num : 当失败用例达到 num 个时停止。
  • --lf ( --last-failed ): 只重新运行上次失败的用例。
  • -n auto : 使用 pytest-xdist 插件进行多进程并行测试,大幅提升执行速度(适用于用例间无依赖)。

5.2 Allure 报告的强大之处

执行上述命令后,打开的 Allure 报告会包含以下核心板块:

  • 概览 (Overview) : 显示测试套件的总体情况,通过率、耗时、趋势图等。
  • 类别 (Categories) : 可以自定义失败类别(如产品缺陷、测试环境问题)。
  • 套件 (Suites) : 按测试文件/类展示用例结构,清晰明了。
  • 图形 (Graphs) : 各种统计图表,如按状态、按执行时长分布的图表。
  • 时间线 (Timeline) : 展示用例执行的时序,分析性能瓶颈。
  • 行为 (Behaviors) : 如果你使用了 @allure.story @allure.feature ,这里会按功能/故事聚合用例。
  • 包 (Packages) : 按 Python 包结构展示。

报告中最重要的部分是每个用例的详情页 ,里面会完整展示:

  • @allure.step 定义的每一步操作。
  • 每个步骤下的请求和响应详情(如果客户端日志配置得当)。
  • 断言失败的具体原因和差异对比。
  • 通过 allure.attach 附加的截图或日志文件。

这份报告是向非技术人员(如产品经理、项目经理)展示测试结果的最佳载体,因为它足够直观。

5.3 集成到 CI/CD 流水线

自动化测试只有集成到 CI/CD 中才能发挥最大价值。以 Jenkins 为例,通常的步骤是:

  1. 代码库(如 Git)触发 Jenkins 任务。
  2. Jenkins 拉取最新代码,创建虚拟环境,安装依赖 ( pip install -r requirements.txt )。
  3. 执行测试命令: pytest --alluredir=./allure-results
  4. 使用 Allure Jenkins Plugin 读取 ./allure-results 目录并发布报告。
  5. 如果测试失败,可以配置邮件通知或即时通讯工具(如钉钉、企业微信)告警。

关键是要在 CI 环境中正确安装 Allure 命令行工具。可以通过包管理器(如 apt, yum)或直接下载二进制包完成。

6. 实战中的常见问题与优化技巧

在实际项目中摸爬滚打,总会遇到一些坑。这里分享几个高频问题和解决思路。

6.1 接口依赖与测试数据管理

  • 问题 :订单测试依赖已存在的商品和用户。如何在测试前准备好这些数据?
  • 方案
    1. Fixture 依赖链 :创建 product_fixture user_fixture ,在 order_fixture 中依赖它们。确保执行顺序。
    2. 调用准备接口 :在 fixture 或用例 setup 中,直接调用后台的“数据准备”接口(如果存在)来创建临时数据。
    3. 数据库操作 :对于复杂依赖,在 fixture 中通过代码直接操作测试数据库,插入所需数据。 务必注意 :操作后要可靠地清理,避免污染后续测试。可以使用 yield fixture 或在 pytest finalizer 中清理。
    4. 独立测试环境 :为自动化测试准备一套独立的、可随时重置的测试环境,这是最根本的解决方案。

6.2 处理动态参数和鉴权

  • 问题 :很多接口需要当前时间戳、随机字符串,或者依赖上一个接口的返回值(如订单号)。
  • 方案
    • 动态生成 :在请求前用 Python 代码实时生成,如 timestamp = int(time.time())
    • 提取与传递 :使用 PyTest 的 fixture 或类属性来传递值。
      @pytest.fixture
      def create_order_first(auth_client):
          resp = auth_client.post("/order", json={...})
          order_id = resp.json()["data"]["orderId"]
          yield order_id
          # 测试后清理订单
      
      def test_pay_order(auth_client, create_order_first):
          # create_order_first fixture 返回了 order_id
          pay_data = {"orderId": create_order_first, "amount": 100}
          auth_client.post("/pay", json=pay_data)
      

6.3 测试稳定性与 flaky tests

  • 问题 :用例偶尔失败,可能是网络抖动、第三方依赖不稳定或环境数据问题。
  • 方案
    1. 重试机制 :对非幂等的查询类接口,可以使用 pytest-rerunfailures 插件,为不稳定的用例添加重试标记 @pytest.mark.flaky(reruns=3, reruns_delay=2)
    2. 更健壮的断言 :不要断言过于精确的值(如完整的错误信息字符串),可以断言关键字段或使用正则表达式匹配部分内容。
    3. 设置合理的超时 :在封装的 ApiClient 中为 requests 设置 timeout 参数,避免因网络慢导致测试假死。
    4. 隔离与清理 :确保每个用例都是独立的,不会因为前一个用例遗留的数据或状态而失败。

6.4 Excel 维护的痛点与演进

  • 问题 :Excel 用例多了之后,维护起来麻烦,且无法做版本对比(二进制文件 diff 困难)。
  • 演进方向
    • 短期 :规范 Excel 模板,使用固定的列名,并编写简单的 GUI 工具或脚本辅助编辑。
    • 中期 :迁移到 YAML JSON 文件。它们同样是文本,可读性好,且易于版本管理。 pytest 可以很方便地读取这些格式进行参数化。
    • 长期 :对于大型团队,考虑引入测试用例管理系统(如 TestLink, Jira + Zephyr),并通过 API 将用例同步到自动化框架中。或者,直接使用 pytest @pytest.mark.parametrize 配合 Python 数据结构(列表、字典)在代码中管理简单用例。

6.5 Allure 报告优化

  • 添加环境信息 :在 reports/allure-results 目录下创建一个 environment.properties 文件,内容如:
    base_url=https://test.env.com
    python_version=3.9.0
    pytest_version=7.0.0
    
    这样报告中会显示测试运行环境。
  • 分类失败用例 :在 conftest.py 中配置 Allure 分类规则,将不同的失败原因归类,例如“前端缺陷”、“后端缺陷”、“环境问题”。
    # conftest.py
    import allure
    def pytest_collection_modifyitems(items):
        for item in items:
            # 可以根据item.nodeid或标记,动态添加allure特性
            if "login" in item.nodeid:
                item.add_marker(allure.feature("登录模块"))
    

这套 Python+Requests+PyTest+Excel+Allure 的方案,其魅力在于它的 渐进式 可组合性 。你可以从最简单的 Requests 写几个测试脚本开始,然后引入 PyTest 来组织用例,再慢慢加入数据驱动和精美报告。每一步都能立刻感受到效率的提升。它可能不是功能最全的,但绝对是 性价比最高、最易于理解和掌控 的接口自动化入门与进阶方案。当你熟练运用这些工具后,你会发现,自动化测试不再是枯燥的脚本编写,而是一种提升研发质量与效率的优雅工程实践。

更多推荐