Python自动化测试框架:unittest、pytest、Selenium、requests和Pytest-BDD

发布时间:2026/10/12 11:21:30

Python自动化测试框架:unittest、pytest、Selenium、requests和Pytest-BDD 前言这个标题里有一个需要先纠正的说法requests不是测试框架。requests是一个 HTTP 客户端库它只负责发请求、收响应跟「组织测试用例、收集测试结果、生成报告」这些测试框架的职责完全无关。它出现在自动化测试话题里是因为写接口测试时常常用它来发请求——它是被测试代码调用的工具不是承载测试的框架。同理Selenium严格说也不是「测试框架」而是浏览器自动化驱动库它把「打开浏览器、点按钮、读文本」这些动作暴露成 Python 方法至于怎么组织用例、怎么断言还是交给unittest或pytest。把前提理清之后标题里这五个名字其实分属四类各司其职类别名字定位来源测试框架unittest内核自带类式用例自带断言方法标准库测试框架pytest第三方函数式用例裸assert需安装浏览器驱动Selenium驱动真实浏览器做端到端操作需安装BDD 工具pytest-bdd把 Gherkin 的场景文本映射到 pytest 用例需安装HTTP 辅助requests在测试里发 HTTP 请求需安装本文按这个分类逐个讲它们的定位与分工并说明它们通常怎么组合。注意requests只作为「测试里的辅助工具」出现本文不把它当框架讲。版本提示按 PyPI 元数据最新的pytest、selenium、pytest-bdd都声明requires_python为3.10unittest属于标准库随解释器走。Python 2.7 已于2020 年 1 月 1 日停止维护下面一律用 Python 3 写法例如断言用assertEqual而不是 2 时代的种种别名习惯print用函数形式。一、unittest标准库自带的测试框架unittest直接import就能用零依赖。它的组织方式是类 方法测试类继承unittest.TestCase方法名以test开头才会被收集。# 适用于 Python 3.8import unittestdef add(a, b):return a bclass TestAdd(unittest.TestCase):def setUp(self):# 每个 test_ 方法执行前都会跑一次self.samples [1, 2, 3]def tearDown(self):# 每个 test_ 方法执行后都会跑一次用来清理self.samples Nonedef test_add_positive(self):self.assertEqual(add(1, 2), 3)def test_add_negative(self):self.assertEqual(add(-1, -2), -3)def test_sum_of_samples(self):self.assertEqual(sum(self.samples), 6)if __name__ __main__:unittest.main()要点断言是方法assertEqual、assertTrue、assertIn、assertRaises等名字写在TestCase上。写错名字不会报「断言失败」而是直接AttributeError。setUp/tearDown是每条用例前后各跑一次如果希望整个类只准备一次用setUpClass/tearDownClass它们是类方法。保存为test_*.py后可以用python -m unittest discover自动发现并运行。二、pytest更轻的第三方测试框架pytest需要pip install pytest。它最大的特点是不需要继承任何基类普通函数就是用例断言直接用 Python 的assert——失败时 pytest 会做「断言内省」把表达式两边的实际值都打出来所以不必去记几十个assertXxx方法名。# 适用于 Python 3.10需要 pip install pytestimport pytestdef add(a, b):return a bdef test_add_positive():assert add(1, 2) 3pytest.mark.parametrize(a, b, expected, [(1, 2, 3),(-1, -2, -3),(0, 0, 0),])def test_add_many(a, b, expected):assert add(a, b) expectedpytest.fixturedef samples():fixture把测试需要的数据/资源准备好由参数名注入。return [1, 2, 3]def test_sum_of_samples(samples):assert sum(samples) 6要点pytest.mark.parametrize把一组数据展开成多条独立用例失败时能精确指出是哪组数据挂了。fixture用pytest.fixture声明用例只要在参数列表里写上同名参数就能拿到不需要手工调用、不需要继承。fixture 还能声明作用域函数级、类级、模块级等来做复用与清理。运行方式是命令行pytest或python -m pytest后者能保证用的是当前解释器对应的 pytest。两者的分工可以这样理解新项目优先pytest不需要额外依赖或要交付到受限环境时用unittest。它们不是互斥的——pytest能直接收集并运行unittest.TestCase写成的用例。三、Selenium驱动浏览器的工具库Selenium解决的问题是「用户界面行为」点按钮、填表单、等待元素出现、读取渲染后的文本。这些是纯 HTTP 请求库做不到的因为浏览器要执行 JavaScript 才能把页面渲染出来。# 适用于 Python 3.10需要 pip install selenium且本机装有 Chromefrom selenium import webdriverfrom selenium.webdriver.common.by import Bydef test_page_title():driver webdriver.Chrome() # 启动一个浏览器会话try:driver.get(https://example.com/)heading driver.find_element(By.TAG_NAME, h1)assert heading.textfinally:driver.quit() # 无论如何都要退出否则留下僵尸进程关键在于谁在启动时帮你把驱动准备好。Selenium 需要 chromedriver、geckodriver 这类浏览器驱动从 Selenium 4.6 起官方提供了Selenium Manager——官方文档称它是「Selenium 官方的驱动管理器」随每个 Selenium 版本一起发布Selenium的各个语言绑定默认会调用它因此不需要你手工下载驱动或改代码。它在驱动不可用时才介入会自动发现本机浏览器版本、下载匹配的驱动并缓存到本地缓存目录。再强调一次Selenium是驱动库不是框架。真正的用例组织仍然由pytest或unittest完成——上面那个函数能被 pytest 直接收集运行就是因为它写成了 pytest 认得的普通函数。四、pytest-bdd把场景文本映射到 pytestBDD行为驱动开发Behavior-Driven Development想让「业务人员也能读的用例描述」直接变成可执行的测试。pytest-bdd把 Gherkin 语法Given/When/Then的场景文件和方法绑定起来而运行器仍然是 pytest。先写一个.feature文件Feature: 购物车Scenario: 加入一件商品Given 购物车是空的When 我加入一件价格为 10 的商品Then 购物车总额应该是 10再用装饰器把它接上# 适用于 Python 3.10需要 pip install pytest-bddfrom pytest_bdd import scenario, given, when, thenscenario(cart.feature, 加入一件商品)def test_add_one_item():这个空函数是一个占位用例steps 会在它之前执行。given(购物车是空的, target_fixturecart)def empty_cart():return []when(我加入一件价格为 10 的商品)def add_item(cart):cart.append(10)then(购物车总额应该是 10)def check_total(cart):assert sum(cart) 10要点scenario(文件.feature, 场景名)把某个场景绑定到一个测试函数这个函数体本身通常是空的Given/When/Then步骤会在它之前按顺序执行。步骤函数可以用target_fixture把返回值变成下游步骤共享的 fixture例子里的cart就是这样在三个步骤之间传递的。步骤函数本身也是普通函数可以用assert、可以抛异常失败了 pytest 照常报告。pytest-bdd的价值在于用例描述与实现分离改业务描述不用动断言代码改实现也不影响场景文本的可读性。代价是多了一层Given/When/Then的映射小项目里可能显得啰嗦。五、requests它在测试里到底是什么角色回到开头那个纠正requests是 HTTP 客户端库它的工作是构造请求、发送、解析响应。在自动化测试体系里它扮演的是辅助工具——测试「接口」时用它发请求再用assert断言响应。# 适用于 Python 3.10需要 pip install requests pytestimport pytestimport requestsdef test_public_api_shape():对一个公开的只读接口做最基本的契约检查。r requests.get(https://example.com/api/status, timeout10)assert r.status_code 200assert r.headers[Content-Type].startswith(application/json)payload r.json()assert isinstance(payload, dict)assert version in payload把它放进这个分类表里位置就清楚了名字是不是「测试框架」真正角色unittest是标准库测试框架pytest是第三方测试框架也是前者的替代/超集Selenium否浏览器自动化驱动库pytest-bdd否是插件挂在 pytest 上的 BDD 插件requests否HTTP 客户端库测试里的辅助工具它们常见的组合方式是用pytest组织用例和 fixture用requests测接口用Selenium测界面需要业务可读场景时加pytest-bdd。unittest则在不想引入第三方依赖时顶替pytest的位置。顺便说一句合规与伦理用requests或Selenium做测试时目标应该是你自己负责的系统或明确提供测试环境的公开接口。拿它们去批量打扰别人的站点无论包装成「压测」还是「爬虫」都不合适——限速、可识别 UA、遵守 robots.txt 这些规则在测试场景里同样适用。常见坑点1. 把requests当测试框架。❌ 在介绍「自动化测试框架」时把requests和pytest并列以为它负责收集和运行用例。 ✅requests只发 HTTP 请求用例收集、断言报告由pytest/unittest负责。2.unittest里把断言写成assert x y却奇怪地「全过」。❌ 在TestCase子类里用普通函数名如check_foo命名用例 —— 不会被收集自然也不失败。 ✅ 方法名必须以test开头且断言优先用self.assertEqual等方法报告信息更全。3.setUp当成「整个类只跑一次」。❌ 把昂贵的初始化写在setUp里以为只执行一次 —— 它每条用例前都跑。 ✅ 一次性准备用setUpClass类方法每条用例前的准备才用setUp。4. Selenium 忘了driver.quit()。❌ 测试抛异常后直接退出浏览器进程残留跑几十条用例后机器被拖垮。 ✅ 用try / finally保证driver.quit()一定执行用 pytest 时可以写成 fixture 的清理段。5. 以为 Selenium 要手工下载驱动。❌ 到处找「chromedriver 与 Chrome 版本对应表」然后手动塞进 PATH。 ✅ Selenium 4.6 起自带的 Selenium Manager 会默认处理驱动的发现、下载与缓存只有在它解决不了时才需要手工指定。6.pytest-bdd的步骤文本与 feature 文件对不上。❌ feature 里写When 我加入一件价格为 10 的商品when装饰器里写的是另一个字面量 —— 场景找不到步骤报StepDefinitionNotFoundError。 ✅ 装饰器里的字符串必须与 feature 文件逐字一致重复的步骤说明可以抽成公共步骤。7. 测试直接打真实生产环境。❌requests.get()和Selenium都指向线上地址测试一跑就给线上刷流量。 ✅ 指向测试环境或本地服务确需访问公开接口时也要限速、只做只读检查。8. 认为Selenium就是「测试框架」于是也拿它去跑接口测试。❌ 用Selenium去调接口 —— 启动整个浏览器只为发一个 HTTP 请求慢且脆弱。 ✅ 接口层面用requests只有需要真实渲染和交互时才用Selenium。总结名字类别一句话职责安装方式unittest测试框架类式用例、自带断言标准库免装pytest测试框架函数式用例、裸assert、fixture、参数化pip install pytestSelenium浏览器驱动操作真实浏览器做端到端测试pip install seleniumpytest-bddBDD 插件把 Gherkin 场景映射成 pytest 用例pip install pytest-bddrequestsHTTP 客户端在测试里发请求属于工具而非框架pip install requests回到标题把这五个名字并称「自动化测试框架」是一种笼统的说法。准确的理解是——两个框架unittest、pytest负责「怎么组织与运行测试」一个插件pytest-bdd负责「怎么用业务语言描述测试」两个库Selenium、requests负责「怎么与被测系统交互」。分清这四层选型时就不会再拿浏览器驱动去做接口测试也不会指望 HTTP 客户端帮你生成测试报告。
延伸阅读

更多相关文章

2026/10/12 11:16:29

Mono.defer 详解:响应式编程中执行时机、选型边界与实战避坑

先说个真实经历。有次我给一个老接口做响应式改造,代码写完单测全绿,结果联调阶段对端反馈“同一个请求两次返回的时间不一样,而且差得离谱”。我查了两天一夜,最后定位到一行Mono.just(System.currentTimeMillis())—— 这行代码…

2026/10/12 11:16:29

SpringBoot邮件集成:从配置到高可用的全链路实践

1. 项目概述:为什么SpringBoot整合Mail不是“配个配置就完事”的小事“SpringBoot整合mail邮箱”这八个字,看起来平平无奇,像极了教程里一句轻描淡写的“三步接入邮件功能”。但我在某高校实验室带学生做毕业设计、在某公司支撑内部运维平台时…

2026/10/12 11:16:29

水壶问题本质是贝祖定理:用最大公约数判定可达性

1. 这个“水壶问题”到底在考什么?——别被名字骗了,它不是生活技巧题“Die Hard Problem”——听到这个名字,很多人第一反应是动作片里布鲁斯威利斯在楼顶倒腾水桶的惊险场面。但实际在算法与数学领域,它指的是一类经典的状态空间…

2026/10/12 12:36:51

Windows批处理驱动MATLAB自动参数扫描:原理与实战

在Windows下用批处理自动运行MATLAB并不断更改参数,是我在做参数扫描仿真时被逼出来的一套方案。当时要跑十几组参数,每组运行三分钟,手动改参数、点运行、等结果、再复制数据,整个人像机器人一样盯屏幕。后来我用了一个最简单的办…

2026/10/12 12:36:51

Open Claw开源机械爪:低成本3D打印与舵机控制实战指南

1. 项目概述:Open Claw是什么,能做什么先明确一下,Open Claw是一个完全开源的机械爪项目。我看到这个标题时第一反应是:终于有人把机械爪从实验室里解放出来了。过去几年,机械臂、仿生机器人被炒得很热,但你…

2026/10/12 12:36:51

Markdown 嵌套多级列表的树形语义重构:基于栈拓扑消除缩进歧义

在面向企业级知识工程构建高保真 RAG(检索增强生成)系统与运维审计智能体时,数据处理团队所面对的最具欺骗性、也最容易引发隐性逻辑断裂的数据形态,莫过于非结构化文档中的多级嵌套列表(Hierarchical Nested Lists&am…

2026/10/12 12:36:51

OpenClaw进阶玩法:多飞书机器人部署指南与TaoToken统一接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/12 12:01:26

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/11 0:02:13

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/12 0:04:22

绝缘子缺陷检测数据集清洗与工业级训练实战指南

简介:本资源是面向电力AI研发人员、工业视觉工程师及智能巡检系统开发者的绝缘子缺陷检测专用YOLO格式数据集,解决无人机航拍场景下绝缘子破损、污闪、积雪等9类典型缺陷的精准识别与定位难题。数据集共2139张真实巡检图像(含训练/验证/测试集…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑