10.pytest的插件allure生成企业级测试报告

Pytest 插件 Allure 生成企业级测试报告详解

1. 什么是 Allure

1.1 Allure 简介

Allure 是一个轻量级、灵活的测试报告框架,专门用于生成美观、详细的企业级测试报告。它最初是为 Java 测试框架设计的,但现在也完美支持 Python 的 pytest 框架。

1.2 为什么需要 Allure

在日常测试工作中,我们经常会遇到以下问题:

  1. 测试报告不够直观:pytest 默认的报告只是简单的文本输出,不够美观
  2. 信息不够详细:无法清楚地看到测试步骤、截图、日志等详细信息
  3. 历史记录缺失:无法查看测试历史趋势和对比
  4. 团队协作不便:无法方便地分享和展示测试结果给团队成员和领导
  5. 问题定位困难:当测试失败时,难以快速定位问题原因

没有 Allure 的情况

# 运行测试
pytest test_example.py -v

# 输出结果
======================== test session starts ==========================
platform win32 -- Python 3.9.0, pytest-7.0.0
collected 3 items

test_example.py::test_login PASSED                                  [ 33%]
test_example.py::test_create_user PASSED                            [ 66%]
test_example.py::test_delete_user FAILED                            [100%]

======================== FAILURES ==========================
test_delete_user FAILED
AssertionError: assert False

问题

  • 报告不够美观,只是简单的文本
  • 无法看到详细的测试步骤
  • 无法附加截图、日志等附件
  • 无法查看历史趋势
  • 不适合向领导汇报

使用 Allure 后

# 运行测试并生成 Allure 报告
pytest test_example.py --alluredir=./allure-results
allure serve ./allure-results

# 生成一个美观的 HTML 报告,包含:
# - 详细的测试步骤
# - 测试截图
# - 测试日志
# - 历史趋势图
# - 测试分类和标签
# - 环境信息

优势

  • 美观的 HTML 报告,适合向领导汇报
  • 详细的测试步骤,方便定位问题
  • 支持截图、日志等附件
  • 历史趋势分析
  • 测试分类和标签管理
  • 团队协作友好

1.3 Allure 的主要特点

  1. 美观的界面:现代化的 Web 界面,支持多种图表和可视化
  2. 详细的步骤:可以记录测试的每个步骤,方便问题定位
  3. 丰富的附件:支持截图、日志、文件等多种附件
  4. 历史追踪:可以查看测试历史趋势和对比
  5. 分类管理:支持测试分类、标签、优先级等管理
  6. 环境信息:可以记录测试环境信息
  7. 多语言支持:支持多种编程语言和测试框架

1.4 Allure 报告的核心概念

在深入学习 Allure 之前,我们需要了解几个核心概念:

  1. Test Case(测试用例):一个独立的测试函数
  2. Test Step(测试步骤):测试用例中的具体操作步骤
  3. Attachment(附件):测试过程中附加的截图、日志等文件
  4. Label(标签):用于分类和标记测试用例
  5. Suite(套件):测试用例的集合
  6. History(历史):测试执行的历史记录

2. 安装 Allure

2.1 安装 pytest-allure-adaptor 或 allure-pytest

Allure 在 Python 中有两个主要的适配器:

  1. allure-pytest(推荐):官方维护,功能更全面
  2. pytest-allure-adaptor:旧版本,不推荐使用

安装 allure-pytest

pip install allure-pytest

指定版本安装

# 安装特定版本
pip install allure-pytest==2.13.2

# 安装最新版本
pip install allure-pytest --upgrade

2.2 安装 Allure 命令行工具

Allure 报告需要 Allure 命令行工具来生成。安装方法因操作系统而异:

2.2.1 Windows 安装

方法 1:使用 Scoop 安装(推荐)

# 先安装 Scoop(如果没有)
# 在 PowerShell 中执行
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
irm get.scoop.sh | iex

# 使用 Scoop 安装 Allure
scoop install allure

方法 2:手动安装

# 1. 下载 Allure
# 访问 https://github.com/allure-framework/allure2/releases
# 下载 allure-2.13.2.zip(或最新版本)

# 2. 解压到某个目录,例如 C:allure

# 3. 将 C:allurebin 添加到系统环境变量 PATH 中

# 4. 验证安装
allure --version

2.2.2 macOS 安装

使用 Homebrew 安装

brew install allure

2.2.3 Linux 安装

Ubuntu/Debian

# 添加仓库
sudo apt-add-repository ppa:qameta/allure
sudo apt-get update

# 安装
sudo apt-get install allure

或者使用 Snap

sudo snap install allure --classic

2.3 验证安装

验证 Python 包安装

pip show allure-pytest

输出示例

Name: allure-pytest
Version: 2.13.2
Summary: Allure pytest integration
Location: /path/to/site-packages

验证 Allure 命令行工具

allure --version

输出示例

2.13.2

查看 Allure 帮助

allure --help

3. Allure 基本使用

3.1 最简单的示例

让我们从一个最简单的例子开始:

创建测试文件 test_simple.py

import pytest
import allure

def test_add():
    """测试加法"""
    assert 1 + 1 == 2

def test_subtract():
    """测试减法"""
    assert 5 - 3 == 2

运行测试并生成 Allure 报告

# 1. 运行测试,生成 Allure 结果数据
pytest test_simple.py --alluredir=./allure-results

# 2. 生成并打开报告
allure serve ./allure-results

说明

  • --alluredir=./allure-results:指定 Allure 结果数据的保存目录
  • allure serve ./allure-results:生成临时报告并在浏览器中打开

3.2 查看报告

执行 allure serve ./allure-results 后,会自动:

  1. 生成 HTML 报告
  2. 启动本地服务器
  3. 在默认浏览器中打开报告

报告界面包含

  • Overview(概览):测试执行的整体情况
  • Suites(套件):按测试套件查看
  • Graphs(图表):测试结果的可视化图表
  • Behaviors(行为):按行为分类查看
  • Packages(包):按包/模块查看

3.3 生成静态报告

除了使用 allure serve 查看临时报告,还可以生成静态 HTML 报告:

# 生成静态报告
allure generate ./allure-results -o ./allure-report --clean

# 查看报告(需要手动打开)
# Windows: 在文件管理器中打开 allure-report/index.html
# macOS: open allure-report/index.html
# Linux: xdg-open allure-report/index.html

参数说明

  • -o ./allure-report:指定报告输出目录
  • --clean:清理输出目录(如果已存在)

4. Allure 装饰器详解

4.1 @allure.title – 设置测试标题

默认情况下,Allure 使用函数名作为测试标题。使用 @allure.title 可以自定义更友好的标题。

示例 1:基本用法

import allure
import pytest

@allure.title("用户登录测试")
def test_login():
    """测试用户登录功能"""
    assert True

@allure.title("创建新用户")
def test_create_user():
    """测试创建用户功能"""
    assert True

示例 2:动态标题

import allure
import pytest

@pytest.mark.parametrize("username", ["admin", "user", "guest"])
@allure.title("测试用户 {username} 的登录功能")
def test_login_with_username(username):
    """使用参数化测试,标题中包含参数"""
    assert username in ["admin", "user", "guest"]

示例 3:使用函数参数

import allure

@allure.title("测试用户 {user_id} 的信息")
def test_user_info(user_id):
    """标题中使用函数参数"""
    assert user_id > 0

4.2 @allure.description – 添加测试描述

使用 @allure.description 可以为测试用例添加详细的描述信息。

示例 1:使用装饰器参数

import allure

@allure.description("""
这是一个详细的测试描述:
1. 测试用户登录功能
2. 验证用户名和密码
3. 检查登录后的跳转
""")
def test_login():
    assert True

示例 2:使用文档字符串

import allure

@allure.description
def test_login():
    """
    测试用户登录功能

    前置条件:
    - 用户已注册
    - 数据库连接正常

    测试步骤:
    1. 打开登录页面
    2. 输入用户名和密码
    3. 点击登录按钮

    预期结果:
    - 登录成功
    - 跳转到首页
    """
    assert True

示例 3:动态描述

import allure

def test_with_dynamic_description():
    """测试动态描述"""
    allure.dynamic.description("这是动态添加的描述")
    assert True

4.3 @allure.step – 定义测试步骤

@allure.step 是 Allure 中最重要的装饰器之一,用于定义测试步骤。步骤会在报告中详细显示,方便定位问题。

示例 1:基本用法

import allure

@allure.step("打开登录页面")
def open_login_page():
    """打开登录页面"""
    print("正在打开登录页面...")
    return True

@allure.step("输入用户名: {username}")
def input_username(username):
    """输入用户名"""
    print(f"正在输入用户名: {username}")
    return True

@allure.step("输入密码")
def input_password():
    """输入密码"""
    print("正在输入密码...")
    return True

@allure.step("点击登录按钮")
def click_login_button():
    """点击登录按钮"""
    print("正在点击登录按钮...")
    return True

def test_login():
    """测试登录流程"""
    open_login_page()
    input_username("admin")
    input_password()
    click_login_button()
    assert True

示例 2:在测试函数中使用步骤

import allure

def test_login_with_steps():
    """测试登录流程(在测试函数中定义步骤)"""

    with allure.step("打开登录页面"):
        print("打开登录页面")

    with allure.step("输入用户名和密码"):
        username = "admin"
        password = "123456"
        print(f"输入用户名: {username}")
        print(f"输入密码: {password}")

    with allure.step("点击登录按钮"):
        print("点击登录按钮")

    with allure.step("验证登录结果"):
        assert True

示例 3:步骤嵌套

import allure

@allure.step("准备测试数据")
def prepare_data():
    """准备测试数据"""
    with allure.step("连接数据库"):
        print("连接数据库")

    with allure.step("查询用户信息"):
        print("查询用户信息")

    with allure.step("清理临时数据"):
        print("清理临时数据")

def test_with_nested_steps():
    """测试嵌套步骤"""
    prepare_data()
    assert True

示例 4:步骤参数化

import allure

@allure.step("处理用户 {user_id}")
def process_user(user_id, action):
    """处理用户操作"""
    print(f"处理用户 {user_id} 的 {action} 操作")
    return True

def test_process_users():
    """测试处理多个用户"""
    users = [1, 2, 3]
    for user_id in users:
        process_user(user_id, "登录")
    assert True

4.4 @allure.severity – 设置测试优先级

使用 @allure.severity 可以标记测试用例的优先级。

优先级级别

  • allure.severity_level.BLOCKER:阻塞级别(最高)
  • allure.severity_level.CRITICAL:严重级别
  • allure.severity_level.NORMAL:正常级别(默认)
  • allure.severity_level.MINOR:次要级别
  • allure.severity_level.TRIVIAL:轻微级别(最低)

示例

import allure
import pytest

@allure.severity(allure.severity_level.BLOCKER)
def test_critical_login():
    """关键登录测试"""
    assert True

@allure.severity(allure.severity_level.CRITICAL)
def test_important_feature():
    """重要功能测试"""
    assert True

@allure.severity(allure.severity_level.NORMAL)
def test_normal_feature():
    """普通功能测试"""
    assert True

@allure.severity(allure.severity_level.MINOR)
def test_minor_feature():
    """次要功能测试"""
    assert True

@allure.severity(allure.severity_level.TRIVIAL)
def test_trivial_feature():
    """轻微功能测试"""
    assert True

按优先级运行测试

# 只运行阻塞级别的测试
pytest test_example.py --alluredir=./allure-results -s -v --allure-severities=blocker

# 运行阻塞和严重级别的测试
pytest test_example.py --alluredir=./allure-results -s -v --allure-severities=blocker,critical

4.5 @allure.feature – 功能分类

使用 @allure.feature 可以将测试用例按功能模块分类。

示例

import allure

@allure.feature("用户管理")
def test_create_user():
    """创建用户"""
    assert True

@allure.feature("用户管理")
def test_delete_user():
    """删除用户"""
    assert True

@allure.feature("订单管理")
def test_create_order():
    """创建订单"""
    assert True

@allure.feature("订单管理")
def test_cancel_order():
    """取消订单"""
    assert True

4.6 @allure.story – 用户故事

@allure.story 通常与 @allure.feature 配合使用,表示更细粒度的用户故事。

示例

import allure

@allure.feature("用户管理")
@allure.story("用户注册")
def test_user_register():
    """用户注册"""
    assert True

@allure.feature("用户管理")
@allure.story("用户登录")
def test_user_login():
    """用户登录"""
    assert True

@allure.feature("用户管理")
@allure.story("用户注销")
def test_user_logout():
    """用户注销"""
    assert True

@allure.feature("订单管理")
@allure.story("创建订单")
def test_create_order():
    """创建订单"""
    assert True

@allure.feature("订单管理")
@allure.story("查看订单")
def test_view_order():
    """查看订单"""
    assert True

按功能或故事运行测试

# 只运行"用户管理"功能的测试
pytest test_example.py --alluredir=./allure-results -s -v --allure-features="用户管理"

# 只运行"用户登录"故事的测试
pytest test_example.py --alluredir=./allure-results -s -v --allure-stories="用户登录"

4.7 @allure.suite – 测试套件

使用 @allure.suite 可以将测试用例分组到不同的测试套件中。

示例

import allure

@allure.suite("冒烟测试")
def test_smoke_1():
    """冒烟测试 1"""
    assert True

@allure.suite("冒烟测试")
def test_smoke_2():
    """冒烟测试 2"""
    assert True

@allure.suite("回归测试")
def test_regression_1():
    """回归测试 1"""
    assert True

@allure.suite("回归测试")
def test_regression_2():
    """回归测试 2"""
    assert True

4.8 @allure.tag – 标签

使用 @allure.tag 可以为测试用例添加标签,方便分类和筛选。

示例

import allure

@allure.tag("API", "快速")
def test_api_quick():
    """快速 API 测试"""
    assert True

@allure.tag("UI", "慢速")
def test_ui_slow():
    """慢速 UI 测试"""
    assert True

@allure.tag("数据库", "重要")
def test_database_important():
    """重要的数据库测试"""
    assert True

4.9 组合使用多个装饰器

在实际项目中,通常会组合使用多个装饰器:

示例

import allure
import pytest

@allure.feature("用户管理")
@allure.story("用户登录")
@allure.severity(allure.severity_level.BLOCKER)
@allure.title("测试管理员登录功能")
@allure.description("""
测试管理员登录功能:
1. 输入正确的管理员账号和密码
2. 验证登录成功
3. 检查用户权限
""")
def test_admin_login():
    """测试管理员登录"""
    with allure.step("打开登录页面"):
        print("打开登录页面")

    with allure.step("输入管理员账号和密码"):
        username = "admin"
        password = "admin123"
        print(f"输入用户名: {username}")
        print(f"输入密码: {password}")

    with allure.step("点击登录按钮"):
        print("点击登录按钮")

    with allure.step("验证登录成功"):
        assert True

5. Allure 附件功能

5.1 添加截图

在 UI 自动化测试中,截图是非常重要的调试工具。Allure 支持在测试过程中添加截图。

示例 1:基本截图

import allure
from PIL import Image
import io

def test_with_screenshot():
    """测试带截图"""
    # 模拟截图(实际项目中从 Selenium 等工具获取)
    img = Image.new('RGB', (800, 600), color='red')
    img_bytes = io.BytesIO()
    img.save(img_bytes, format='PNG')
    img_bytes.seek(0)

    # 添加截图到 Allure 报告
    allure.attach(
        img_bytes.read(),
        name="登录页面截图",
        attachment_type=allure.attachment_type.PNG
    )

    assert True

示例 2:Selenium 截图

import allure
from selenium import webdriver

def test_login_with_screenshot():
    """登录测试带截图"""
    driver = webdriver.Chrome()

    try:
        driver.get("https://example.com/login")

        # 截图并添加到报告
        screenshot = driver.get_screenshot_as_png()
        allure.attach(
            screenshot,
            name="登录页面",
            attachment_type=allure.attachment_type.PNG
        )

        # 执行登录操作
        driver.find_element_by_id("username").send_keys("admin")
        driver.find_element_by_id("password").send_keys("123456")

        # 登录后截图
        driver.find_element_by_id("login-btn").click()
        screenshot_after = driver.get_screenshot_as_png()
        allure.attach(
            screenshot_after,
            name="登录后页面",
            attachment_type=allure.attachment_type.PNG
        )

        assert True
    finally:
        driver.quit()

示例 3:失败时自动截图

import allure
import pytest
from selenium import webdriver

@pytest.fixture(scope="function")
def driver():
    """WebDriver fixture"""
    driver = webdriver.Chrome()
    yield driver
    # 如果测试失败,自动截图
    if pytest.current_test_failed:
        screenshot = driver.get_screenshot_as_png()
        allure.attach(
            screenshot,
            name="失败截图",
            attachment_type=allure.attachment_type.PNG
        )
    driver.quit()

def test_login_fail_auto_screenshot(driver):
    """测试失败时自动截图"""
    driver.get("https://example.com/login")
    # 故意让测试失败
    assert False, "测试失败,应该自动截图"

5.2 添加文本附件

示例

import allure

def test_with_text_attachment():
    """测试带文本附件"""
    # 添加普通文本
    allure.attach(
        "这是测试日志信息n包含多行内容",
        name="测试日志",
        attachment_type=allure.attachment_type.TEXT
    )

    # 添加 JSON 数据
    import json
    data = {"username": "admin", "status": "active"}
    allure.attach(
        json.dumps(data, indent=2, ensure_ascii=False),
        name="用户数据",
        attachment_type=allure.attachment_type.JSON
    )

    assert True

5.3 添加 HTML 附件

示例

import allure

def test_with_html_attachment():
    """测试带 HTML 附件"""
    html_content = """
    <html>
        <head><title>测试页面</title></head>
        <body>
            <h1>这是测试 HTML 内容</h1>
            <p>包含一些测试信息</p>
            <table border="1">
                <tr><th>用户名</th><th>状态</th></tr>
                <tr><td>admin</td><td>active</td></tr>
            </table>
        </body>
    </html>
    """

    allure.attach(
        html_content,
        name="测试页面",
        attachment_type=allure.attachment_type.HTML
    )

    assert True

5.4 添加文件附件

示例

import allure

def test_with_file_attachment():
    """测试带文件附件"""
    # 读取文件内容
    with open("test_data.txt", "r", encoding="utf-8") as f:
        file_content = f.read()

    # 添加文件附件
    allure.attach(
        file_content,
        name="测试数据文件",
        attachment_type=allure.attachment_type.TEXT
    )

    assert True

5.5 附件类型列表

Allure 支持以下附件类型:

allure.attachment_type.TEXT        # 文本
allure.attachment_type.CSV         # CSV 文件
allure.attachment_type.TSV         # TSV 文件
allure.attachment_type.URI_LIST    # URI 列表
allure.attachment_type.HTML        # HTML
allure.attachment_type.XML         # XML
allure.attachment_type.JSON        # JSON
allure.attachment_type.YAML        # YAML
allure.attachment_type.PNG         # PNG 图片
allure.attachment_type.JPG         # JPG 图片
allure.attachment_type.SVG         # SVG 图片
allure.attachment_type.GIF         # GIF 图片
allure.attachment_type.BMP         # BMP 图片
allure.attachment_type.WEBM        # WEBM 视频
allure.attachment_type.MP4         # MP4 视频
allure.attachment_type.PDF         # PDF 文件

6. Allure 环境信息配置

6.1 什么是环境信息

环境信息用于记录测试执行的环境,包括操作系统、Python 版本、浏览器版本等。这些信息会在 Allure 报告的”Environment”部分显示。

6.2 创建环境配置文件

创建 environment.properties 文件

# 操作系统信息
OS=Windows 10
OS.Version=10.0.19045

# Python 信息
Python.Version=3.9.0
Pytest.Version=7.0.0

# 浏览器信息
Browser=Chrome
Browser.Version=91.0

# 测试环境
Environment=Test
Base.URL=https://test.example.com

# 数据库信息
Database=MySQL
Database.Version=8.0

6.3 使用环境配置文件

方法 1:手动指定环境文件

# 将 environment.properties 放在 allure-results 目录中
pytest test_example.py --alluredir=./allure-results
# 手动复制 environment.properties 到 allure-results 目录
copy environment.properties allure-results/

# 生成报告
allure generate ./allure-results -o ./allure-report --clean

方法 2:使用 pytest fixture 自动生成

import pytest
import allure
import platform
import sys

@pytest.fixture(scope="session", autouse=True)
def configure_allure_environment():
    """配置 Allure 环境信息"""
    environment = {
        "OS": platform.system(),
        "OS Version": platform.version(),
        "Python Version": sys.version,
        "Pytest Version": pytest.__version__,
    }

    # 写入环境信息到 allure-results 目录
    import os
    allure_dir = "./allure-results"
    os.makedirs(allure_dir, exist_ok=True)

    env_file = os.path.join(allure_dir, "environment.properties")
    with open(env_file, "w", encoding="utf-8") as f:
        for key, value in environment.items():
            f.write(f"{key}={value}n")

    yield

6.4 动态添加环境信息

示例

import allure
import platform
import sys

def test_with_environment_info():
    """测试带环境信息"""
    # 动态添加环境信息
    allure.dynamic.environment(
        OS=platform.system(),
        Python=sys.version,
        Pytest=pytest.__version__
    )

    assert True

7. Allure 历史记录

7.1 什么是历史记录

Allure 历史记录功能可以保存测试执行的历史数据,用于:

  • 查看测试趋势
  • 对比不同时间的测试结果
  • 分析测试稳定性

7.2 启用历史记录

方法 1:使用 allure-results 目录结构

# 第一次运行
pytest test_example.py --alluredir=./allure-results
allure generate ./allure-results -o ./allure-report --clean

# 第二次运行(历史记录会自动保存)
pytest test_example.py --alluredir=./allure-results
allure generate ./allure-results -o ./allure-report
# 注意:不要使用 --clean,这样会保留历史记录

方法 2:使用 CI/CD 集成

# .github/workflows/test.yml 示例
name: Tests
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run tests
        run: |
          pytest --alluredir=./allure-results
      - name: Generate report
        run: |
          allure generate ./allure-results -o ./allure-report
      - name: Archive report
        uses: actions/upload-artifact@v2
        with:
          name: allure-report
          path: allure-report

7.3 查看历史趋势

在 Allure 报告的”Graphs”页面,可以查看:

  • 测试用例数量的趋势
  • 通过率趋势
  • 失败率趋势
  • 执行时间趋势

8. 完整的实战示例

8.1 示例 1:用户登录测试

创建 test_login.py

import allure
import pytest
from selenium import webdriver
import time

@allure.feature("用户管理")
@allure.story("用户登录")
class TestLogin:
    """用户登录测试类"""

    @pytest.fixture(scope="class")
    def driver(self):
        """WebDriver fixture"""
        driver = webdriver.Chrome()
        yield driver
        driver.quit()

    @allure.title("测试管理员登录")
    @allure.severity(allure.severity_level.BLOCKER)
    @allure.description("""
    测试管理员登录功能:
    1. 打开登录页面
    2. 输入管理员账号和密码
    3. 点击登录按钮
    4. 验证登录成功
    """)
    def test_admin_login(self, driver):
        """测试管理员登录"""
        with allure.step("打开登录页面"):
            driver.get("https://example.com/login")
            time.sleep(1)
            screenshot = driver.get_screenshot_as_png()
            allure.attach(
                screenshot,
                name="登录页面",
                attachment_type=allure.attachment_type.PNG
            )

        with allure.step("输入管理员账号和密码"):
            driver.find_element_by_id("username").send_keys("admin")
            driver.find_element_by_id("password").send_keys("admin123")
            allure.attach(
                "用户名: adminn密码: admin123",
                name="登录信息",
                attachment_type=allure.attachment_type.TEXT
            )

        with allure.step("点击登录按钮"):
            driver.find_element_by_id("login-btn").click()
            time.sleep(2)
            screenshot = driver.get_screenshot_as_png()
            allure.attach(
                screenshot,
                name="登录后页面",
                attachment_type=allure.attachment_type.PNG
            )

        with allure.step("验证登录成功"):
            assert "dashboard" in driver.current_url
            assert driver.find_element_by_id("user-info").is_displayed()

    @allure.title("测试普通用户登录")
    @allure.severity(allure.severity_level.NORMAL)
    def test_user_login(self, driver):
        """测试普通用户登录"""
        with allure.step("打开登录页面"):
            driver.get("https://example.com/login")

        with allure.step("输入普通用户账号和密码"):
            driver.find_element_by_id("username").send_keys("user")
            driver.find_element_by_id("password").send_keys("user123")

        with allure.step("点击登录按钮"):
            driver.find_element_by_id("login-btn").click()
            time.sleep(2)

        with allure.step("验证登录成功"):
            assert "dashboard" in driver.current_url

    @allure.title("测试登录失败(错误密码)")
    @allure.severity(allure.severity_level.NORMAL)
    def test_login_failed(self, driver):
        """测试登录失败"""
        with allure.step("打开登录页面"):
            driver.get("https://example.com/login")

        with allure.step("输入错误的密码"):
            driver.find_element_by_id("username").send_keys("admin")
            driver.find_element_by_id("password").send_keys("wrong_password")

        with allure.step("点击登录按钮"):
            driver.find_element_by_id("login-btn").click()
            time.sleep(2)

        with allure.step("验证登录失败提示"):
            error_msg = driver.find_element_by_id("error-message").text
            allure.attach(
                f"错误信息: {error_msg}",
                name="错误信息",
                attachment_type=allure.attachment_type.TEXT
            )
            assert "密码错误" in error_msg

运行测试

pytest test_login.py --alluredir=./allure-results -v
allure serve ./allure-results

8.2 示例 2:API 测试

创建 test_api.py

import allure
import pytest
import requests
import json

@allure.feature("API 测试")
class TestAPI:
    """API 测试类"""

    BASE_URL = "https://api.example.com"

    @allure.story("用户 API")
    @allure.title("测试获取用户信息")
    @allure.severity(allure.severity_level.CRITICAL)
    def test_get_user_info(self):
        """测试获取用户信息"""
        user_id = 1

        with allure.step(f"发送 GET 请求获取用户 {user_id} 的信息"):
            url = f"{self.BASE_URL}/users/{user_id}"
            response = requests.get(url)

            allure.attach(
                f"请求 URL: {url}n请求方法: GET",
                name="请求信息",
                attachment_type=allure.attachment_type.TEXT
            )

        with allure.step("验证响应状态码"):
            assert response.status_code == 200
            allure.attach(
                f"状态码: {response.status_code}",
                name="响应状态码",
                attachment_type=allure.attachment_type.TEXT
            )

        with allure.step("验证响应数据"):
            data = response.json()
            allure.attach(
                json.dumps(data, indent=2, ensure_ascii=False),
                name="响应数据",
                attachment_type=allure.attachment_type.JSON
            )
            assert data["id"] == user_id
            assert "name" in data

    @allure.story("用户 API")
    @allure.title("测试创建用户")
    @allure.severity(allure.severity_level.CRITICAL)
    def test_create_user(self):
        """测试创建用户"""
        new_user = {
            "name": "测试用户",
            "email": "test@example.com",
            "age": 25
        }

        with allure.step("发送 POST 请求创建用户"):
            url = f"{self.BASE_URL}/users"
            response = requests.post(url, json=new_user)

            allure.attach(
                json.dumps(new_user, indent=2, ensure_ascii=False),
                name="请求数据",
                attachment_type=allure.attachment_type.JSON
            )

        with allure.step("验证创建成功"):
            assert response.status_code == 201
            data = response.json()
            allure.attach(
                json.dumps(data, indent=2, ensure_ascii=False),
                name="响应数据",
                attachment_type=allure.attachment_type.JSON
            )
            assert data["name"] == new_user["name"]
            assert "id" in data

    @allure.story("订单 API")
    @allure.title("测试获取订单列表")
    @allure.severity(allure.severity_level.NORMAL)
    def test_get_orders(self):
        """测试获取订单列表"""
        with allure.step("发送 GET 请求获取订单列表"):
            url = f"{self.BASE_URL}/orders"
            response = requests.get(url)

        with allure.step("验证响应"):
            assert response.status_code == 200
            orders = response.json()
            allure.attach(
                f"订单数量: {len(orders)}",
                name="订单统计",
                attachment_type=allure.attachment_type.TEXT
            )
            assert isinstance(orders, list)

运行测试

pytest test_api.py --alluredir=./allure-results -v
allure serve ./allure-results

8.3 示例 3:数据库测试

创建 test_database.py

import allure
import pytest
import pymysql

@allure.feature("数据库测试")
class TestDatabase:
    """数据库测试类"""

    @pytest.fixture(scope="class")
    def db_connection(self):
        """数据库连接 fixture"""
        connection = pymysql.connect(
            host='localhost',
            user='test',
            password='test123',
            database='test_db',
            charset='utf8mb4'
        )
        yield connection
        connection.close()

    @allure.story("用户表操作")
    @allure.title("测试查询用户")
    @allure.severity(allure.severity_level.CRITICAL)
    def test_query_user(self, db_connection):
        """测试查询用户"""
        with allure.step("执行 SQL 查询"):
            cursor = db_connection.cursor()
            sql = "SELECT * FROM users WHERE id = %s"
            cursor.execute(sql, (1,))
            result = cursor.fetchone()
            cursor.close()

            allure.attach(
                f"SQL: {sql}n参数: (1,)n结果: {result}",
                name="SQL 执行信息",
                attachment_type=allure.attachment_type.TEXT
            )

        with allure.step("验证查询结果"):
            assert result is not None
            assert result[0] == 1

    @allure.story("用户表操作")
    @allure.title("测试插入用户")
    @allure.severity(allure.severity_level.CRITICAL)
    def test_insert_user(self, db_connection):
        """测试插入用户"""
        with allure.step("执行 SQL 插入"):
            cursor = db_connection.cursor()
            sql = "INSERT INTO users (name, email) VALUES (%s, %s)"
            cursor.execute(sql, ("测试用户", "test@example.com"))
            db_connection.commit()
            user_id = cursor.lastrowid
            cursor.close()

            allure.attach(
                f"SQL: {sql}n参数: ('测试用户', 'test@example.com')n新用户ID: {user_id}",
                name="SQL 执行信息",
                attachment_type=allure.attachment_type.TEXT
            )

        with allure.step("验证插入成功"):
            assert user_id > 0

运行测试

pytest test_database.py --alluredir=./allure-results -v
allure serve ./allure-results

发表评论