
我2016年开始带测试团队的时候正赶上公司全面自动化的浪潮。技术总监拍板所有业务模块必须写自动化用例目标是把手动测试占比压到30%以下。三个月后复盘自动化用例堆了2000多条但维护成本高得吓人每周光修脚本就要花掉一个人三天工作量而真正跑出价值的场景不到四分之一。那段时间我一直在反思一个问题自动化和手动测试之间的选择真的只是效率高低这么简单吗后来做了不少大型项目的测试方案设计又面试了几百个测试工程师才慢慢形成一套自己的判断框架。这篇就来聊聊我这套框架的核心思路包括两种测试方式到底在解决什么问题、各自擅长什么场景、以及从团队和个人的角度该怎么制定选择策略。先说结论自动化测试和手动测试从来不是替代关系而是一条测试链路里的两个互补支点。选错了轻则浪费人力重则让整个质量体系失去意义。下面我会从成本结构、场景匹配、技术落地、团队协作这几个维度把这件事拆开说清楚。1. 自动化测试的效率账本哪些成本经常被低估很多团队上自动化第一理由是省时间。但真实算下来自动化的时间成本分布和大多数人想象的不一样。一个自动化用例从无到有到稳定运行至少包含四个环节的成本脚本开发、环境维护、数据准备、结果排查。开发只是冰山一角后面三块才是长期吞噬人力的地方。举个我实际经历的例子。之前给一个电商中台做接口自动化大概覆盖了150个核心接口。初期开发脚本用了一个半月每天维护脚本大概半小时但是每次要跑全量回归环境准备和数据重置需要额外半天。遇到商品服务、促销服务、订单服务三个模块的依赖数据互相耦合一旦联调环境被别的团队动了脚本跑出来一片红排查下来全是环境问题。这笔账算清楚之后我对自动化的预期管理就变了。现在我在设计自动化方案时会先做一个单用例全生命周期成本估算。开发一条接口用例如果花1小时那它后续每跑一次的维护成本刀率大约是开发成本的10%到20%。如果这条用例每周能跑20次以上那自动化绝对是划算的如果一个月才跑一次就得认真想想是不是手动点一下反而更便宜。1.1 用三个指标决定一条用例值不值得自动化在真实项目中我不会去追求自动化覆盖率达到多少而是对每一条用例回答三个问题触发频率够不够高执行场景是否稳定可重复结果判定是否够客观触发频率是首要指标。自动化适合高频重复这几乎是共识但很多人忽略重复不等于同一动作反复点。真正能发挥自动化价值的是每一次执行数据都不一样但校验规则一样的场景。比如登录接口开发者每次用不同账号不同密码但断言逻辑都是状态码200且拿到了token。这种场景跑100次和跑1次脚本改动量几乎为零收益却翻了百倍。场景稳定性也很关键。我记得有个测试工程师曾开心地汇报他给前端UI做了完整的自动化用例。两周之后产品经理改了一个按钮的文字又过了一周改了另一个弹窗的交互顺序结果脚本每周坏一次。到最后他每天的工作就是修脚本比原来手动测试还累。UI自动化的脆弱性不是工具的问题而是被测对象本身变动频繁。做这个决策时要判断元素定位的路径是不是够稳定如果前端三天两头调整DOM结构这类用例自动化的成本会失控。结果判定客观性决定了排查成本的量级。接口返回一串JSON断言状态码和关键字段这是客观的。但图像界面里弹窗是否遮挡了按钮这类问题靠脚本去判断就要复杂很多。不是不能做而是要引入视觉比对、图像识别之类的技术调试成本陡增。所以在设计阶段我会优先把容易做客观断言的场景自动化主观判定类场景先留给人。1.2 维护成本中最大的隐性黑洞测试数据从事自动化测试这些年我踩过最深的坑就是测试数据管理。脚本稳定跑一个月突然某天挂了所有人都以为是代码问题查了半天发现是一条测试账号被运营同事手动改了密码。这种场景我经历的次数太多后来学乖了凡是涉及账号、订单、优惠券这类有状态的数据一律通过接口去构造不依赖任何人手动维护的公共测试环境。具体做法很简单每个自动化用例开始前先调用准备数据的接口跑完以后走清理接口把数据销毁。这样每条用例从逻辑上是原子化的不会因为上一条用例留下的脏数据导致下一条失败。很多测试同学写脚本时只顾着点击和断言从来不关心数据生命周期等出了问题才反应过来这时候排查成本早就超标了。如果你发现团队的自动化用例经常莫名其妙失败先不要怀疑业务代码去查测试数据和执行环境大概率问题都在这里。2. 手动测试不可替代的核心阵地探索、感知与业务判断自动化测试圈有个词叫脚本孤儿——写出来的脚本越来越多但能稳定产出价值的越来越少。其中一个关键原因是太多人把自动化用在了它最不擅长的探索性测试上。手动测试的不可替代性体现在三个层面上。第一是感性层面的用户体验判断第二是探索式测试里那种不按套路出牌的随机性第三是复杂业务场景里需要综合判断结果对不对的能力。这三类能力有一个共同点需要人的经验和直觉这个恰恰是脚本最难模拟的。2.1 视觉细节与主观体验为什么自动化很难替代人眼我参与过一个智慧大屏项目的测试界面上有很多实时刷新的图表数据每隔五秒滚动一次。如果按照自动化逻辑去写断言我可以验证数据有没有更新但很难判断更新后的图表好不好看、布局乱不乱。有一次版本更新后所有图表的tooltip都被截断了但自动化脚本全部通过因为数据校验都是合法的。最后是测试同学手动过了一遍大屏才发现的。这种视觉细节问题在后台管理系统、数据大屏、复杂报表里特别常见。自动化可以帮你确认功能存在和数据正确但是否好看、是否清晰、是否容易误读这种主观体验短时间内还是要靠人眼。这不是技术的局限而是质量标准本身的模糊性。只要质量定义里包含主观成分手动测试就有存在的必要。2.2 探索式测试脚本永远给不了你的意外发现探索式测试是手动测试最核心的看家本领。它的价值在于不按预期路径操作而是基于测试人员的经验和对系统的理解去尝试那些边界状态、异常操作、竞态条件。举个例子之前测试一个支付流程自动化和手动同时进行。自动化脚本严格按选择支付方式→输入金额→确认支付→支付成功的路径走全绿。手动测试的同学却试着在支付请求发出的同一瞬间断网然后恢复网络发现页面显示支付失败、但后台订单状态竟然变成了已支付。这种问题靠预定义脚本几乎不可能发现因为它触发的前提是精确到毫秒级的异常时序。所以我从来不会说探索式测试效率低。它看起来没有脚本那么高的执行效率但发现深层次缺陷的能力是任何既定用例都无法复制的。一个合格的测试方案应当在自动化覆盖了主体功能、回归风险之后留出专门的人力做探索式测试最好是让最有经验的测试人员上。2.3 复杂业务规则下的判断力当正确没有标准答案有些业务场景里正确不是一个布尔值而是一个需要综合多个因素权衡的判断。比如风控系统的触发策略同样的交易行为在不同用户画像下可能是完全不同的处理结果。自动化脚本能验证风控有没有拦截但很难替换人判断这个拦截逻辑在当前业务阶段是否合理。这种场景大量存在于金融、医疗、政务类项目。我的经验是在这些领域手动测试不仅不能省反而要往业务专家方向培养。测试人员对业务的理解深度直接决定了他能不能发现系统实现和业务预期不一致的问题。3. 选择策略的核心框架基于风险与回报的动态决策既然自动化和手动测试各有领地那二者之间到底该怎么配比我给团队定的策略从来不是拍脑袋得到一个固定比例比如70%自动化、30%手动而是基于场景的四个变量做动态决策稳定性、频率、可判定性、业务影响。3.1 四个决策变量与场景匹配表这四个变量单独拿出来说都很简单但放到一起就会产生一些很有意思的判断。这里直接给一张我常用的决策表变量偏自动化偏手动需求稳定性模块稳定接口很少变化产品迭代快UI频繁调整执行频率每日回归、持续集成必跑每月甚至更低频的冒烟验证结果可判定性接口返回、状态码、数据校验视觉效果、复杂体验、主观判断业务影响核心链路出问题影响大必须反复验证低风险辅助功能即使出问题影响也有限这套表的理解关键在于第四行业务影响。很多人只盯着前三个变量做技术判断忽略了业务层级的影响。核心链路登录、下单、支付值得用高成本方式去守护哪怕自动化成本高一些也值得投入而一些低频、低风险的功能比如帮助中心的一个FAQ展示花大量精力去做自动化反而是负收益手动测试点两下就完事。3.2 一个具体项目的配比复盘从拍脑袋到有章法2021年有个金融类App项目测试周期只有一个月需求方要求自动化覆盖率达到80%。我拿到需求后没有直接答应而是先把模块按上面四个变量过了一遍。支付、账户、实名认证这类核心链路需求稳定、执行频率高、结果客观上自动化没问题。但首页信息流、行情图表、活动营销这些模块UI变动频繁、视觉体验要求高自动化收益极低。最终我的方案是核心交易链路自动化覆盖率达到90%以上活动类和展示类模块完全放弃自动化全部交给手动测试做探索式验证。表面上总覆盖率只有50%出头但发布后线上缺陷率控制在0.3%以内整个项目的自动化维护成本也比预想低很多。这个配比后来也成了我对外做测试方案咨询时的标准打法。3.3 什么时候必须退回手动测试一个被忽视的决策我见过不少团队自动化上线之后就不愿意再碰手动即使自动化效果已经很差。这里有一个非常实际的心理因素自动化看起来更高级手动测试显得廉价团队担心退回手动会被质疑能力退步。但实际上回头在测试策略里是特别正常的一件事。当一个模块进入快速原型期或者技术方案面临重构又或者业务规则频繁变更时手动测试往往比自动化更经济。判断是否退回手动有个信号只要花费在脚本维护上的时间超过脚本执行所节省的时间这个模块的自动化就处于负收益状态。这时候果断砍掉自动化保留手动回归把腾出来的资源投入其他更需要自动化的场景才是理性的选择。4. 自动化测试落地工程化从脚本思维到框架思维说到自动化测试的落地必须认清楚一件事写脚本只是最表层的工作真正决定自动化成败的是脚本之外的工程化能力。我发现很多测试工程师写了两三年能用的脚本却从来没有认真思考过框架设计、稳定性和可维护性这种情况招进来之后反而会变成团队的维护负担。4.1 接口自动化从0到1pytest是绕不开的根基目前国内最主流的接口自动化框架绕不开pytest。为什么我推荐pytest而不是unittest核心在于fixture机制、插件生态和断言表达的简洁度。fixture可以很方便地处理测试前置和后置conftest.py做全局配置搭配pytest-html生成测试报告再配合Allure出漂亮的展示这套组合基本是行业标准配置。我一般建议团队用这样的目录结构组织接口自动化项目testcases/ # 测试用例 test_login.py test_order.py test_payment.py common/ # 公共封装 request_client.py # 请求封装 assert_util.py # 断言工具 data_factory.py # 测试数据构造 config/ # 环境配置 dev_config.yaml staging_config.yaml reports/ # 测试报告输出 conftest.py # fixture全局定义这个结构跑起来之后新手也能很快定位到用例位置维护成本会低很多。项目里另外几个重要文件是pytest.ini和conftest.py它们决定了框架的扩展边界。下面这个conftest.py的示例很典型定义了token获取和请求客户端支撑所有用例跑起来。# conftest.py import pytest from common.request_client import RequestClient from common.data_factory import DataFactory pytest.fixture(scopesession) def base_url(): return https://api.example.com pytest.fixture(scopesession) def auth_token(base_url): # 公共登录获取 tokensession 级别只执行一次 client RequestClient(base_url) resp client.post(/auth/login, json{ username: test_user, password: hashed_password }) assert resp.status_code 200 return resp.json()[token] pytest.fixture() def api_client(base_url, auth_token): # 每个用例拿到独立的 client带上 token 请求头 return RequestClient(base_url, tokenauth_token)我自己带团队时有个要求所有的请求封装必须收敛在RequestClient里面用例层面不允许直接裸调requests库。这样一旦接口认证方式从token变成签名或者OAuth只需要改一个文件全套用例都能跟着升级。4.2 UI自动化的稳定第一原则少用sleep多用显式等待相比接口自动化UI自动化的稳定性问题更突出。最大的坑就是时间等待。很多初学者喜欢到处写time.sleep(3)跑的时候看起来还行一旦网络波动或者页面加载变慢脚本就大面积失败。正确做法是用显式等待Selenium和Appium都内置了WebDriverWait机制。from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 等待登录按钮可点击最长等10秒 login_btn WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, login-btn)) ) login_btn.click()time.sleep是固定等待无论页面加载要1秒还是5秒都得等同样的时间WebDriverWait是条件等待页面准备好了就立即继续比固定等待既稳又高效。Appium做移动端测试时同理而且Appium对iOS和Android的生态支持比较成熟是移动端自动化绕不开的选择。另外元素定位策略也直接影响稳定性。我见过很多脚本用绝对xpath路径来定位比如/html/body/div[1]/div[3]/div[2]/button前端稍微调整一下层级脚本就废了。相比之下优先使用id、name、data-testid这类稳定的属性实在找不到再用相对xpath配合文本内容定位。这个原则看起来简单实际项目里能帮你挡掉至少一半的维护灾难。4.3 自动化报告与持续集成的最后一公里自动化测试跑完如果不把结果用清晰的方式展现出来那这套体系的价值要打五折。测试报告应该回答三个问题这次发布风险有多大哪些功能被验证过失败用例具体挂在哪里Allure在这块表现很好它能把每个步骤的截图、请求参数、响应内容都记录下来排查问题非常方便。更进一步自动化测试必须接入持续集成让用例在每次代码提交后自动触发。我在项目中用的模式是开发提交代码后触发接口自动化全量回归跑完自动生成Allure报告并推送到团队群。整个流程下来大家不用等测试人员手动去点回归效率和反馈速度都成倍提升。5. 手动测试团队的进阶之路从点按钮到业务守护者聊完技术必须说说人。很多测试新人最容易犯的认知错误是把手动测试和点点点画等号。真正高级的手动测试根本不是低价值劳动而是一种需要深厚业务积累和技术敏感度的高难度工作。关键区别在于低水平手动测试是照着用例执行、发现bug就提交高水平手动测试是理解用户场景、主动设计测试思路、在探索中发现系统深层的风险。5.1 手动测试工程师的核心竞争力测试设计能力我面试手动测试工程师的时候很少问你会不会写脚本更多是给一个具体业务场景问你会怎么测。比如给定一个转账功能金额范围是0.01到50000问候选人会设计哪些测试点。大部分人会回答边界值0.01、50000、超出范围这些是基础。但优秀的候选人会接着问转账目标账户类型有没有区分对方账户状态是冻结时怎么处理转账过程中网络中断会怎样并发转账是否存在超扣风险这就是测试设计能力的差异。自动化的用例脚本本质上只是执行器而测试设计的质量决定了自动化能覆盖多少风险。哪怕一个测试人员完全不会写代码只要测试设计能力过硬同样能指导自动化用例的产出方向。反过来一个只会写脚本、不懂业务逻辑的人写出来的自动化用例再多也可能在关键风险上留下盲区。5.2 手动和自动化的协作流程谁先谁后谁反馈在实际项目中我喜欢把测试执行拆成两条线自动化负责回归守门手动负责前期的深度验证和发布后的问题追踪。自动化用例的来源一半来自需求分析阶段的用例设计另一半来自手动测试过程中发现的回归场景。也就是说手动测试不只是执行它还是自动化用例的挖掘机。具体流程上一个新功能上线手动测试同学先去跑测试设计和探索式测试把发现的高频回归场景提取出来交给自动化的同事去固化。之后每次迭代自动化用例逐步增加手动测试逐步缩减重复性的回归动作转向更深层的验证。这个流程跑一年之后团队的自动化稳定性和手动测试的探索深度都会同步提升而不是让自动化取代手动把人变成纯粹的脚本维护者。5.3 团队技能矩阵每个测试人员都应该双向生长我建议团队里的测试人员不要把自己定义成自动化工程师或手动测试工程师而是建立一个双向技能矩阵。至少要做到手动测试人员懂得看自动化用例的失败日志能快速判断问题是脚本问题还是产品问题自动化测试人员理解手动测试的核心业务场景能把手动用例的意图转成自动化脚本逻辑。这种双向生长的好处很明显。第一避免团队内部出现懂业务的人不会写代码会写代码的人不懂业务的割裂第二人员的可替代性降低职业安全感反而更强第三跨出测试岗位去理解整个研发流程也为晋升和转型打好基础。6. 让自动化测试与手动测试真正协同的几个实操建议前面讲的都是方法论最后落在实操层面分享几个我这些年反复验证过、也确实见效的具体做法。6.1 用测试金字塔指导分配而不是空谈覆盖率测试金字塔的概念是老生常谈但真正用起来的团队不多。金字塔分三层底层的单元测试数量最多中层的接口测试次之顶层的UI自动化测试最少。很多团队一上来就猛做UI自动化一个UI用例的时间成本和维护成本能顶五个接口用例最后往往得不偿失。我做过最极端的一个项目UI自动化用例只有12条占据金字塔的尖端只覆盖最核心的端到端链路。而接口自动化有400多条单元测试有几千条。最终发布质量很稳UI自动化的维护成本也低。这个案例说明一个道理覆盖率不是越高越好而是越靠近金字塔底层越多越好。测试策略的设计首要任务是性价比。6.2 自动化用例的评审机制和代码评审一样重要自动化用例也需要评审但评审的重点不是脚本写得规范不规范而是用例覆盖的业务风险是否准确、是否跟上了需求变化。我建议每轮迭代都要做一次自动化用例评审测试人员、开发人员、产品经理一起过把已经失去价值的用例删除把新增的风险场景补充进去。有一次评审中产品经理提了一个很小的改动支付成功后新增了一个回跳延迟。听起来无伤大雅但自动化用例里支付成功之后马上断言回跳的URL这次改动会导致用例失败。如果没有评审测试人员可能要花半小时去排查产品没问题但脚本挂了的困惑。有了评审大家提前知道了改动也顺手把用例的等待条件更新了。这种小事做多了团队的整体协作效率会明显提升。6.3 失败用例的根因分类别再让环境背锅自动化跑挂了第一件事不是修脚本而是给失败原因分类。我通常把失败原因分成四类脚本问题、环境问题、数据问题、产品缺陷。每次跑完之后测试人员要把失败用例按这四类统计形成曲线。如果一段时间里环境问题占比过高比如超过30%就得去排查测试环境的稳定性而不是继续埋头修脚本。这个方法对一个长期维护的自动化项目尤其重要。它能帮你量化地看清自动化到底在为谁服务——如果绝大多数失败都是环境问题说明这套自动化体系在真实质量保障上的贡献是有限的需要考虑调整。6.4 AI辅助测试的现实边界什么能做什么不能做最后聊聊现在大火的AI自动化测试。我试用过不少AI辅助工具也关注了业界在这块的实践。目前的AI测试主要在三个方向有价值自动生成测试用例、智能元素定位、失败截图分类。比如让大模型根据产品需求文档自动生成接口测试用例和边界值分析可以显著提升测试设计的效率。但也要清醒地看到AI目前还很难承担那些需要业务判断的探索式测试工作。AI可以帮你找出一条高潜力的测试路径但为什么要测这条路径这个结果是不是合理仍然需要人来把关。所以我的建议是AI作为测试生产力的加速器去用不要指望它替代测试人员的思考。真正靠谱的路径是人负责定义质量目标和决策AI负责提高执行和生成的效率。7. 写在最后一个测试负责人的日常清单这些年带过很多团队也见过很多失败的自动化项目。回头总结我每次接手新项目时都会先强制自己过一遍这个清单避免陷入为自动化而自动化的怪圈。先看被测对象的生命周期模块还有多久会重构如果三个月后就要重构先别急着写自动化。再看团队的人力构成是擅长业务还是擅长代码据此决定自动化投入的节奏。然后盘点现有回归成本如果手动回归一次要三天那自动化再贵都值得上如果手动回归只要半天自动化可能就是伪需求。最后设定退出机制明确哪些模块在什么条件下放弃自动化回到手动测试的怀抱。这些问题的答案比工具选型和技术方案更早出现也更重要。工具和技术是战术选择和取舍才是战略。自动化测试省心还是糟心核心不在你会不会用pytest、Appium、Selenium而在于你有没有想清楚它该被用在什么位置、什么时候该收手。测试这个岗位无论是手动还是自动化本质上都是在为一个目标服务用最合适的方式发现最关键的风险。手动测试的价值在于人的判断力自动化的价值在于机器的执行力和一致性。把两者放在一个动态平衡的框架里去思考质量保障体系才能既高效又可靠。这套框架就是我这篇文章想留给你的最核心的东西。