资讯动态

Python自动化测试基础:从选型到Selenium与Requests实战

发布时间:2026/10/18 9:31:23 来源:尧图企业网站定制
“Python自动化测试”这个词现在几乎是测试岗位技能列表里的标配聊它的人很多能把基础讲透的反而很少。我见过太多人从安装Selenium开始到跑通第一个脚本结束然后卡在“下一步该干嘛”也见过完成了接口自动化的演示却回答不了“为什么用例要这么组织”。这篇文章想把自动化测试的基础摊开聊先判断你的项目到底适不适合自动化再讲Python做自动化的工具链怎么搭配然后落到Selenium和Requests两条主流分支的核心实操最后把我实际操作中踩过的坑和排查思路整理出来。如果你正在从手工测试转向自动化或者已经在用脚本但觉得用例越来越难维护这些内容应该对你有参考价值。1. 动手之前先把自动化测试解决的问题想清楚1.1 自动化测试不是“把手工步骤录下来”很多人一提到自动化测试第一反应就是“让电脑代替人点击页面”。再往前一步很多工具确实提供了录制回放功能录一遍操作、回放出来看起来好像就是自动化了。但我必须说一句可能不太好听的话只会录制回放做不了真正意义上的自动化测试。录制回放的脚本由工具生成和业务理解是脱节的。录下来的每一步都是“输入了什么、点了哪里”却没有“输入是否有效、页面响应是否符合预期”的断言。等下一次页面结构一变录制脚本就得整个重录。我见过一个团队用录制回放写了30多条用例第一轮跑得很开心第二轮发版以后挂了25条最后全部推倒重写——原因就是对业务的建模能力没有沉淀到脚本里脚本只是一堆操作记录。真正有价值的自动化测试是用代码把业务流程、校验逻辑、异常场景固化下来让测试用例变成一个“可运行、可重复、可报告”的程序。通俗一点讲录像是“用手操作并记录过程”而自动化是“用代码描述业务并把结果和预期做比对”。这两者的差距决定了后续会不会踩大坑。1.2 哪些项目真的适合做自动化哪些不适合衡量标准不是“别人都在做”也不是“领导要求上”而是投入产出比。我自己判断一个项目适不适合做自动化主要看三个条件业务逻辑是否稳定。需求天天变、页面每周改版的功能自动化脚本刚写完就失效跑十次修八次。是否需要频繁回归。发版频繁、手工回归工作量大的项目自动化的价值最明显。是否属于核心链路。支付、登录、下单、消息推送这些出问题影响大的模块值得投入自动化。用一张表来对照可能更直观项目特征是否适合自动化说明频繁发版、每周回归核心流程适合回归时间从小时级降到分钟级功能稳定、短期不会重构适合脚本可以长期复用一次性原型、演示Demo不适合开发成本不值得投入功能需求每周变动不适合维护成本高于手工测试纯界面交互频繁改版谨慎界面未稳定前写脚本等于返工同样重要的还有时机问题。我接触过一些项目在页面还没冻结的时候就急着写界面层脚本等产品改了三次UI脚本已经改了三轮。比较好的节奏是功能测试基本稳定、主要流程冻结之后再启动界面自动化建设前期更多投入放在接口层面因为接口比页面稳定得多而且核心链路逻辑大多集中在接口层。1.3 自动化测试的“成本红线”维护成本往往高于编写成本很多团队上自动化只算了第一次写脚本的时间没算后续维护的时间。事实上自动化测试的真正成本大头在维护不在创建。一个典型反面案例是某系统里堆了几百条界面用例覆盖了很多边角功能但主流程每条用例的平均维护成本已经开始超过手工回归一次的成本。最后这段自动化资产不是提效工具反而成了团队的负担。我比较认可的做法是“少而精”用稳定的核心用例跑回归用少量探索性测试覆盖边界。自动化覆盖率不是越高越好真正的指标应该是“自动化用例能不能稳定通过、能不能减少重复劳动”。与其追求用例数量不如把50条核心流程维护扎实让每条用例都有断言的深度和业务价值。这样到了版本迭代后期自动化真正的价值才会浮现出来每次发版前跑一遍所有核心链路一目了然。2. Python自动化测试怎么做选型工具链和架构逻辑2.1 为什么选Python测试生态足够厚选语言本质上选生态。Python在测试领域的“基本盘”非常厚几乎每一个自动化测试环节都有成熟方案库解决的问题适合场景pytest用例组织、执行、断言、fixture所有自动化用例的骨架Selenium浏览器自动化Web界面回归Requests发送HTTP请求、处理响应接口自动化Allure生成测试报告展示执行结果、定位失败pytest-xdist并发执行用例用例多、执行时间长的回归从我实际接触到的团队看用pytest Requests Selenium这套组合作为自动化测试的起点仍然是最稳妥的选择。原因是资料多、案例多、遇到问题搜索一下就有答案。对新入门的朋友来说选一个生态最成熟的工具链比选一个“最新潮”的工具链重要得多。工具链的意义在于解决实际问题不在于展示技术新鲜度。另外Python本身语法简单测试代码的核心一般是“组织请求、断言结果、管理数据”没有太复杂的业务计算逻辑用Python表达这些逻辑比Java、C#轻量很多。团队里有手工测试经验但不擅长写代码的成员学Python的曲线也最平滑。2.2 基础环境搭建虚拟环境和依赖安装环境搭建虽然简单但有个细节值得注意一定要在虚拟环境里装依赖而不是直接往系统Python里装。后面接持续集成流水线时虚拟环境可以直接复用也能避免本机目录被各种版本的包污染。步骤大致是python -m venv venv # Windows 下激活 venv\Scripts\activate # Linux / macOS 下激活 source venv/bin/activate pip install pytest selenium requests allure-pytest安装完验证一下pytest --version python -c import requests; print(requests.__version__)依赖锁定建议使用 requirements.txt。这里有个细节直接执行pip freeze requirements.txt会把很多间接依赖也锁进去文件又大又难维护更推荐手动维护一份顶层依赖清单pytest7.0 selenium4.10 requests2.28 allure-pytest2.12这样后续升级版本时可控程度高也容易排查版本冲突。版本号不要写死用或~给一个小范围兼顾稳定性和升级空间。2.3 pytest的fixture和数据驱动框架的“地基”pytest看起来简单但它的fixture机制才是自动化框架的核心。fixture解决了两类问题测试前的准备工作和测试后的清理工作。打个比方接口测试里要拿登录后的token用fixture写这个逻辑可以只在需要时执行一次后续所有用例共用同一个token避免每条用例都调一遍登录接口。import pytest import requests pytest.fixture(scopesession) def login_token(): resp requests.post( https://api.xxx.com/login, json{username: test_user, password: 123456} ) return resp.json().get(token)scope参数有三种主要的取值function每个用例执行一次、module每个测试文件执行一次、session整个测试会话执行一次。实际经验是登录这种高频操作优先用session级别但要注意token过期时间如果15分钟过期session跑上半小时就会有一批用例挂在401上。这种情况可以给fixture加一个自动续期逻辑或者把token的有效期纳入用例设计。数据驱动也是pytest的强项它能帮你把“同一套逻辑跑多组数据”这件事做得特别干净import pytest pytest.mark.parametrize(a,b,expected, [ (1, 1, 2), (100, 200, 300), (-1, 5, 4), ]) def test_add(a, b, expected): assert a b expected参数化之后一组数据就是一个独立的测试用例执行结果里能明确看出是哪组数据失败。这个特性在做接口自动化时尤其重要因为接口测试最典型的场景就是多组入参、多个预期结果。conftest.py是pytest的另一个重要概念它用于存放跨文件的公共fixture和钩子函数最典型的用法是把登录token、数据库连接、测试环境地址都定义在conftest.py里让各个测试文件直接复用。新手容易忽略conftest.py的目录作用域记住一条规则conftest.py 放在哪个目录它定义的fixture就作用于该目录及其子目录。3. 两条主流分支实操Web自动化与接口自动化3.1 Web自动化核心实操Selenium的定位、等待、操作Web界面自动化最容易崩的地方有三个定位、等待、操作。先说定位。定位元素的优先级基本是稳定的id优先name/class其次CSS选择器和XPath最后考虑。很多页面喜欢生成动态id比如idbtn-12345这种id后面跟着一串数字每次刷新都变这种就不能直接用id定位得用XPath找相对位置driver.find_element(By.XPATH, //div[classorder-panel]//button[contains(text(),提交)])再说等待。等待是整个Web自动化里最影响稳定性的点。最常见的坏习惯是写time.sleep()死等8秒、10秒。能用等待解决的问题sleep不一定解决不了但会让整个执行时间膨胀也会在页面真正挂掉的时候掩盖问题。应优先使用显式等待from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, submit-btn)) )这段代码的逻辑是“最多等10秒一旦条件满足立刻继续”比固定sleep高效得多。显式等待和隐式等待可以一起用但不要混用隐式等待和过长的全局设置否则定位一个不存在的元素时会白等很久。最后是操作。点击之前先确认元素可点输入之前先清空再输入下拉框用Select类处理。有个容易被忽略的点不要在一个用例里反复用find_element去定位同一个元素把元素对象保存下来复用代码更清晰执行也更快。还有一个小建议Web界面用例尽量少而精。界面层跑核心业务主流程边界条件和异常分支放到接口层去覆盖这样整个自动化体系的稳定性会高很多。3.2 接口自动化核心实操Requests串联业务链路接口自动化比界面自动化稳定得多适合作为自动化的先行者。核心就三件事组装请求、校验响应、管理数据关联。requests库封装了HTTP请求的最大痛点。一个基础用例长这样import requests def test_get_user(): resp requests.get( https://api.xxx.com/user/1, headers{Authorization: Bearer token} ) assert resp.status_code 200 data resp.json() assert data[code] success assert data[data][username] test_user业务链路比单接口要复杂一些。比如创建订单接口返回订单ID支付接口要用这个ID这就是数据关联。简单做法是在用例里保存依赖值order_id create_order()[data][order_id] pay_result pay_order(order_id)但更好的做法是把这类业务依赖放到fixture里管理让用例本身只关注业务校验。接口自动化还有一个高频需求是把接口字段校验自动化比如响应里某个字段不能为空、类型必须正确这些断言写清楚就是最基础的契约测试。好的断言不是只检查状态码200而是检查业务成功标志、关键字段值、数据完整性这样失败时才能快速定位到具体问题。另外接口自动化建议引入环境配置管理测试环境、预发环境的地址和账号分离用一个config文件统一管理否则后期环境一多脚本里全是硬编码URL改起来非常痛苦。3.3 报告与日志让执行结果“可说人话”用例写好了执行结果如果是一大堆print输出没法给团队看也很难排查失败原因。pytest本身提供了结果结构再配一个可视化报告会更直观。Allure的基本用法是给用例加两个装饰器import allure allure.title(创建订单-成功场景) allure.description(校验订单创建成功后的响应字段) def test_create_order(): ...然后通过命令行生成报告pytest --alluredirallure_results allure serve allure_results报告的价值不只是展示红和绿更重要的是让失败步骤一眼可查。我通常建议在关键操作里补充上下文信息比如接口的入参、响应耗时、关键返回字段。自动化用例如果连失败原因都要根据日志脑补那它的可维护性会直线下降。日志方面不要用一堆print建议用Python标准库logging输出到文件配合报告一起看。print在pytest里会被截断或污染结果而logging可以分级输出定位问题时效率高很多。4. 实战过程中最常见的坑和排查思路4.1 元素定位失败不要只想着重写XPathWeb自动化里报NoSuchElementException是最常见的问题。多数人第一反应是重写XPath写了几次还不行就开始怀疑框架版本。实际上绝大多数定位失败根源在前面几个环节。排查顺序建议是页面是不是还没加载完。先看元素是否存在用显式等待解决优先级最高。元素是不是在iframe里。iframe内部的元素必须先切到对应的frame才能定位driver.switch_to.frame(main_frame) # 操作iframe内部元素... driver.switch_to.default_content()页面是否有多个相同属性元素。动态id、带空格文本、随机属性后缀都会造成定位失败或定位到了错误的元素。这种情况先打开浏览器开发者工具把元素特征和人工观察对齐再写选择器。我见过不少人卡在定位问题上卡到半夜其实打开开发者工具从Elements里复制一段唯一特征重新写一下选择器就好了。切忌为了绕过问题写很长很难读的复杂XPath后面维护的人看到会非常痛苦。4.2 接口用例“昨天能跑今天挂”先怀疑数据而不是代码接口自动化最常见的问题不是脚本错了而是环境数据变了。昨天测试环境的账号有余额今天被另一个用例消费完了昨天有个订单状态是pending今天有几个用例把它改成了paid。数据和用例互相影响脚本就开始飘红。解决办法围绕“用例独立性”展开用例执行前主动构造所需数据执行后清理数据尽量不依赖环境里的存量数据涉及共享数据的用例用一个带随机数的唯一标识避免数据冲突不要把用例顺序当成设计的一部分任何两条用例都不应该依赖前一条的执行结果。可以顺手引入pytest-randomly插件让用例每次执行顺序随机化用来提前暴露顺序依赖问题。逻辑很简单如果用例之间有隐藏依赖随机顺序跑几轮就会让问题自己跳出来。4.3 环境切换和数据管理用配置隔离代替复制粘贴在测试环境、预发环境之间切换最常见的一个坏做法是用字典硬编码URL然后每个文件里都去引用。一旦要加新环境就得满项目改。我建议把环境配置集中到一个文件里切换环境只改一处。YAML配置示例test: base_url: https://test-api.xxx.com user: test_user password: 123456 staging: base_url: https://staging-api.xxx.com user: staging_user password: 654321代码里读取时只需要传入环境名import os import yaml env os.getenv(TEST_ENV, test) config yaml.safe_load(open(config.yaml))[env]这种方式最大的好处是用例代码里不出现具体的环境地址运维新加一个环境时不需要改动任何测试代码。这对自动化测试的可维护性提升非常明显。数据库连接字符串、MQ队列名、第三方回调地址也可以放进环境配置统一管理。4.4 持续的排查思路从“为什么挂”到“怎么防止再挂”每次遇到用例失败建议先按一个固定的路径排查复现问题确认是稳定失败还是偶发失败。看日志和报告把失败点缩小到具体操作或具体断言。判断是环境问题、数据问题还是代码问题。如果是环境或数据问题修数据、修配置如果是代码问题再回到脚本和被测对象的结构对齐。我带项目时养成了一个习惯别人问用例为什么挂了我会先问一句“最近有没有人改过被测系统的逻辑”大部分情况下答案都和信息变更有关。自动化测试到了后期维护难点往往不在于写代码而在于完成跨角色的信息对齐产品改了文案、开发改了接口字段、运维改了环境地址都会让脚本飘红。所以养成“变更感知”的习惯远比赛前反复调试脚本更有效率。建议在团队里建立一条简单的变更广播渠道被测系统一有接口或页面改动相关自动化用例的执行结果会立刻说明问题出在哪一环。我自己在实际使用中还有一个体会自动化测试最忌讳的是一上来就追求大而全的平台、框架、数据工厂。先把最小的闭环跑通——一条用例、一份报告、一次定时执行——再逐步扩展这个节奏是最稳的。如果这篇文章里的基础部分能帮你少走一些弯路后面聊框架封装、数据工厂、持续集成的时候起点就会稳很多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑