爬虫自动化测试:Pytest + Allure 漂亮报告生成

在网络爬虫的开发与维护过程中,自动化测试是保障爬虫稳定性、可靠性的核心环节。而一份清晰、美观的测试报告,能帮助开发者快速定位问题、分析测试覆盖度。Pytest 作为 Python 生态中最流行的测试框架,以其简洁的语法和强大的扩展性著称;Allure 则是一款轻量级的开源测试报告工具,支持生成可视化、交互式的 HTML 报告。本文将详细介绍如何结合 Pytest 与 Allure,实现爬虫自动化测试的报告生成。

一、环境准备

1.1 核心依赖安装

首先需要安装 Pytest、Allure-Pytest 适配器以及 Allure 命令行工具,具体步骤如下:

  1. 安装 Python 依赖包打开终端执行以下命令,安装 Pytest 和 Allure-Pytest:

    bash

    运行

    复制代码
    pip install pytest allure-pytest
    • pytest:提供测试用例的编写、执行和管理功能。
    • allure-pytest:Pytest 与 Allure 的桥梁,用于收集测试结果并生成 Allure 兼容的测试数据。
  2. 安装 Allure 命令行工具Allure 命令行工具用于将测试数据转换为 HTML 报告,不同系统的安装方式如下:

    • Windows 系统

      1. 访问 Allure 官方 GitHub 仓库 下载最新版本的 zip 包。
      2. 解压 zip 包到指定目录(如D:\allure-2.24.0)。
      3. 将解压目录下的bin文件夹路径添加到系统环境变量Path中。
    • Linux/Mac 系统 :可以通过包管理器直接安装,以 Ubuntu 为例:

      bash

      运行

      复制代码
      sudo apt-add-repository ppa:qameta/allure
      sudo apt-get update
      sudo apt-get install allure
  3. 验证安装在终端执行以下命令,若能输出对应版本号,则说明安装成功:

    bash

    运行

    复制代码
    pytest --version
    allure --version

1.2 其他依赖

由于本文聚焦于爬虫测试,还需要安装常用的爬虫库,如requests(处理 HTTP 请求)、BeautifulSoup4(解析 HTML)等:

bash

运行

复制代码
pip install requests beautifulsoup4

二、编写爬虫测试用例

以一个简单的豆瓣电影 Top250 爬虫为例,编写测试用例。测试目标包括:请求是否成功、响应数据格式是否正确、核心字段是否存在等。

2.1 爬虫代码实现

新建douban_spider.py文件,编写爬虫核心逻辑:

python

运行

复制代码
import requests
from bs4 import BeautifulSoup

class DoubanSpider:
    def __init__(self):
        self.base_url = "https://movie.douban.com/top250"
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"
        }

    def get_movie_list(self, page=1):
        """获取指定页码的电影列表"""
        params = {"start": (page - 1) * 25, "filter": ""}
        try:
            response = requests.get(self.base_url, headers=self.headers, params=params, timeout=10)
            response.raise_for_status()  # 抛出HTTP错误异常
            soup = BeautifulSoup(response.text, "html.parser")
            movie_items = soup.find_all("div", class_="item")
            movie_list = []
            for item in movie_items:
                title = item.find("span", class_="title").text
                rating = item.find("span", class_="rating_num").text
                movie_list.append({"title": title, "rating": rating})
            return movie_list
        except Exception as e:
            print(f"爬取失败:{e}")
            return []

2.2 Pytest 测试用例编写

新建test_douban_spider.py文件,编写测试用例。Pytest 的测试用例遵循约定优于配置原则:

  • 测试文件以test_开头。
  • 测试类以Test开头。
  • 测试方法以test_开头。

同时,结合 Allure 的装饰器,为测试用例添加描述、分类等信息,让报告更易读:

python

运行

复制代码
import pytest
import allure
from douban_spider import DoubanSpider

@allure.feature("豆瓣电影Top250爬虫测试")  # 测试模块(大分类)
class TestDoubanSpider:
    def setup_class(self):
        """所有测试方法执行前执行一次,初始化爬虫对象"""
        self.spider = DoubanSpider()

    @allure.story("正常页码爬取测试")  # 测试场景(小分类)
    @allure.title("测试第1页电影列表爬取")  # 测试用例标题
    @allure.severity(allure.severity_level.CRITICAL)  # 用例优先级:CRITICAL > HIGH > MEDIUM > LOW > TRIVIAL
    def test_get_movie_list_page1(self):
        movie_list = self.spider.get_movie_list(page=1)
        # 断言:返回结果非空
        assert len(movie_list) > 0, "第1页电影列表为空"
        # 断言:每条数据包含title和rating字段
        for movie in movie_list:
            assert "title" in movie, "电影数据缺少title字段"
            assert "rating" in movie, "电影数据缺少rating字段"
            assert movie["rating"].replace(".", "").isdigit(), "评分格式错误"

    @allure.story("异常页码爬取测试")
    @allure.title("测试第0页电影列表爬取")
    @allure.severity(allure.severity_level.NORMAL)
    def test_get_movie_list_page0(self):
        movie_list = self.spider.get_movie_list(page=0)
        # 断言:异常页码返回空列表
        assert len(movie_list) == 0, "异常页码未返回空列表"

    @allure.story("请求超时测试")
    @allure.title("测试爬虫超时处理")
    @allure.severity(allure.severity_level.HIGH)
    def test_request_timeout(self):
        # 模拟超时:修改超时时间为0.001秒
        import requests
        with pytest.raises(requests.exceptions.Timeout):
            response = requests.get(
                self.spider.base_url,
                headers=self.spider.headers,
                params={"start": 0},
                timeout=0.001
            )

Allure 核心装饰器说明

装饰器 作用
@allure.feature 定义测试模块,如 "爬虫功能测试""接口性能测试"
@allure.story 定义测试场景,属于 feature 的子集,如 "正常请求测试""异常请求测试"
@allure.title 定义测试用例的标题,支持参数化
@allure.severity 定义用例优先级,影响报告中用例的展示排序
@allure.step 定义测试步骤,用于细化测试过程(下文会详细介绍)

三、生成 Allure 测试报告

Allure 生成报告分为两步:执行测试用例生成测试数据将测试数据转换为 HTML 报告

3.1 执行测试用例,生成测试数据

在终端中切换到测试文件所在目录,执行以下命令:

bash

运行

复制代码
pytest test_douban_spider.py --alluredir=./allure-results
  • --alluredir=./allure-results:指定测试数据的输出目录为当前目录下的allure-results文件夹。

执行完成后,会在当前目录生成allure-results文件夹,里面包含 JSON 格式的测试结果数据。

3.2 生成 HTML 报告

执行以下命令,将allure-results中的数据转换为 HTML 报告:

bash

运行

复制代码
allure serve ./allure-results
  • allure serve:启动一个临时的 Web 服务器,自动在浏览器中打开生成的 HTML 报告。

  • 若需要生成静态 HTML 文件(便于分享),可执行以下命令: bash

    运行

    复制代码
    allure generate ./allure-results -o ./allure-report --clean
    • -o ./allure-report:指定静态报告的输出目录。
    • --clean:清空输出目录中的旧报告。

生成的静态报告可以直接通过浏览器打开allure-report文件夹中的index.html文件查看。

四、Allure 报告核心功能解析

Allure 报告提供了丰富的可视化功能,帮助开发者全面分析测试结果,核心模块如下:

4.1 概览页面(Overview)

报告首页展示测试的整体统计信息,包括:

  • 测试用例总数:总用例数、通过数、失败数、跳过数等。
  • 优先级分布 :按severity分类展示不同优先级用例的执行情况。
  • 时间趋势:测试执行的耗时分布。

4.2 用例页面(Behaviors/Suites)

  • Behaviors :按featurestory分类展示测试用例,与我们编写的测试结构一一对应,便于按业务场景查看。
  • Suites:按测试文件和测试类分类展示用例,适合技术视角的分析。

4.3 测试详情页面

点击任意测试用例,可查看详细的执行日志,包括:

  • 用例的标题、优先级、所属模块。
  • 测试步骤的执行情况(若使用@allure.step)。
  • 断言失败的详细信息,帮助快速定位问题。

4.4 自定义测试步骤

为了让报告更清晰,我们可以使用@allure.step装饰器定义测试步骤。修改test_douban_spider.py中的测试用例:

python

运行

复制代码
@allure.story("正常页码爬取测试")
@allure.title("测试第1页电影列表爬取")
@allure.severity(allure.severity_level.CRITICAL)
def test_get_movie_list_page1(self):
    with allure.step("1. 调用爬虫获取第1页电影列表"):
        movie_list = self.spider.get_movie_list(page=1)
    with allure.step("2. 断言电影列表非空"):
        assert len(movie_list) > 0, "第1页电影列表为空"
    with allure.step("3. 断言电影数据字段完整性和格式正确性"):
        for movie in movie_list:
            assert "title" in movie, "电影数据缺少title字段"
            assert "rating" in movie, "电影数据缺少rating字段"
            assert movie["rating"].replace(".", "").isdigit(), "评分格式错误"

重新执行测试并生成报告后,在测试详情中可以看到清晰的步骤划分。

五、高级技巧:参数化测试与报告优化

5.1 参数化测试

Pytest 的@pytest.mark.parametrize装饰器支持参数化测试,可同时测试多个页码的爬取情况,结合 Allure 的标题参数化,让报告更直观:

python

运行

复制代码
@allure.story("正常页码爬取测试")
@allure.severity(allure.severity_level.CRITICAL)
@pytest.mark.parametrize("page", [1, 2, 3])
@allure.title("测试第{page}页电影列表爬取")
def test_get_movie_list_param(self, page):
    movie_list = self.spider.get_movie_list(page=page)
    assert len(movie_list) > 0, f"第{page}页电影列表为空"

5.2 报告中添加附件

在爬虫测试中,可将响应的 HTML 页面、截图等作为附件添加到报告中,方便问题排查。例如,在测试失败时保存响应内容:

python

运行

复制代码
@allure.story("异常请求测试")
@allure.title("测试无效URL爬取")
def test_invalid_url(self):
    invalid_url = "https://movie.douban.com/top250/invalid"
    try:
        response = requests.get(invalid_url, headers=self.spider.headers, timeout=10)
        response.raise_for_status()
    except Exception as e:
        allure.attach(str(e), name="异常信息", attachment_type=allure.attachment_type.TEXT)
        allure.attach(response.text, name="响应内容", attachment_type=allure.attachment_type.HTML)
        raise

六、总结

本文通过豆瓣电影爬虫的实例,详细介绍了Pytest + Allure在爬虫自动化测试中的应用流程:从环境搭建、测试用例编写,到报告生成与分析,再到高级技巧的优化。借助这套组合,开发者可以快速构建稳定的爬虫测试体系,生成美观、实用的测试报告,从而提升爬虫的开发效率和维护质量。

在实际项目中,还可以结合 CI/CD 工具(如 Jenkins、GitHub Actions),实现测试报告的自动生成与发布,进一步提升自动化测试的价值。

相关推荐
深蓝电商API9 小时前
爬虫+消息队列:RabbitMQ vs Kafka vs RocketMQ选型
爬虫·kafka·rabbitmq
TTGGGFF10 小时前
爬虫专栏:破解网站检测selenium反爬——“当前环境正在被调试“”
爬虫·selenium·测试工具
Data_agent1 天前
京东商品视频API,Python请求示例
java·开发语言·爬虫·python
csdn_aspnet1 天前
如何用爬虫、机器学习识别方式屏蔽恶意广告
人工智能·爬虫·机器学习
光算科技1 天前
Cloudflare防火墙拦截谷歌爬虫|导致收录失败怎么解决?
爬虫
暗之星瞳1 天前
python爬虫学习——1
爬虫·python·学习
Nick_zcy1 天前
新能源汽车推荐系统分享
爬虫·python·汽车·推荐算法
Logic1011 天前
一份系统化《Python爬虫教程》学习笔记:Python爬虫63个核心案例精讲(含反爬策略与源码剖析)
经验分享·爬虫·python·学习笔记·编程·软件开发
@#---1 天前
爬取b站的网页信息
爬虫·python