给解析函数写单元测试
页面选择器很容易因页面改版而失效。把解析逻辑写成接收 HTML 字符串、返回 Python 数据的纯函数,就可以不用联网也能测试它。
1. 让解析与请求分离
from bs4 import BeautifulSoup
def parse_titles(html: str) -> list[str]:
soup = BeautifulSoup(html, "html.parser")
return [node.get_text(" ", strip=True) for node in soup.select("article h2")]
这个函数没有网络、副作用或文件写入,因此同一输入始终应得到同一输出。
2. 使用 unittest 验证预期
import unittest
class ParseTitlesTest(unittest.TestCase):
def test_extracts_titles(self):
html = "<article><h2>第一篇</h2></article><article><h2>第二篇</h2></article>"
self.assertEqual(parse_titles(html), ["第一篇", "第二篇"])
def test_returns_empty_list_when_no_article(self):
self.assertEqual(parse_titles("<p>empty</p>"), [])
if __name__ == "__main__":
unittest.main()
运行:
3. 测试哪些情况
- 正常的多条记录。
- 没有匹配元素时返回空结果。
- 缺少可选字段时的默认值。
- 缺少必填字段时的跳过或报错行为。
- 相对链接能否正确转换为绝对链接。
测试样本应是精简的 HTML fixture,只包含选择器需要的结构。需要回归真实页面问题时,再保存经过脱敏的最小 HTML 片段。
4. 测试不能替代规则检查
单元测试保证“给定 HTML 能按预期解析”,不表示目标站点允许抓取,也不表示线上页面没有变化。因此仍要遵守抓取边界、记录日志,并定期检查样本。