☰
自动化测试与手动测试如何协同?从成本、场景到团队策略
2026/10/10 13:53:43 网站建设 项目流程

我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到1:pytest是绕不开的根基

目前国内最主流的接口自动化框架,绕不开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(scope="session") def base_url(): return "https://api.example.com" @pytest.fixture(scope="session") def auth_token(base_url): # 公共登录获取 token,session 级别只执行一次 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, token=auth_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,而在于你有没有想清楚它该被用在什么位置、什么时候该收手。

测试这个岗位,无论是手动还是自动化,本质上都是在为一个目标服务:用最合适的方式,发现最关键的风险。手动测试的价值在于"人的判断力",自动化的价值在于"机器的执行力和一致性"。把两者放在一个动态平衡的框架里去思考,质量保障体系才能既高效又可靠。这套框架,就是我这篇文章想留给你的最核心的东西。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询