在网络爬虫的开发与维护过程中,自动化测试是保障爬虫稳定性、可靠性的核心环节。而一份清晰、美观的测试报告,能帮助开发者快速定位问题、分析测试覆盖度。Pytest 作为 Python 生态中最流行的测试框架,以其简洁的语法和强大的扩展性著称;Allure 则是一款轻量级的开源测试报告工具,支持生成可视化、交互式的 HTML 报告。本文将详细介绍如何结合 Pytest 与 Allure,实现爬虫自动化测试的报告生成。
一、环境准备
1.1 核心依赖安装
首先需要安装 Pytest、Allure-Pytest 适配器以及 Allure 命令行工具,具体步骤如下:
-
安装 Python 依赖包打开终端执行以下命令,安装 Pytest 和 Allure-Pytest:
bash
运行
pip install pytest allure-pytestpytest:提供测试用例的编写、执行和管理功能。allure-pytest:Pytest 与 Allure 的桥梁,用于收集测试结果并生成 Allure 兼容的测试数据。
-
安装 Allure 命令行工具Allure 命令行工具用于将测试数据转换为 HTML 报告,不同系统的安装方式如下:
-
Windows 系统 :
- 访问 Allure 官方 GitHub 仓库 下载最新版本的 zip 包。
- 解压 zip 包到指定目录(如
D:\allure-2.24.0)。 - 将解压目录下的
bin文件夹路径添加到系统环境变量Path中。
-
Linux/Mac 系统 :可以通过包管理器直接安装,以 Ubuntu 为例:
bash
运行
sudo apt-add-repository ppa:qameta/allure sudo apt-get update sudo apt-get install allure
-
-
验证安装在终端执行以下命令,若能输出对应版本号,则说明安装成功:
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 :按
feature和story分类展示测试用例,与我们编写的测试结构一一对应,便于按业务场景查看。 - 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),实现测试报告的自动生成与发布,进一步提升自动化测试的价值。