有一段时间,我在维护一个已经积累了不少脚本和测试的自动化系统。最初的任务很直接:整理已有能力,修掉明显问题,再把系统优化得更完整。测试跑起来以后,结果也并不差:大部分检查通过,只有少数问题需要修复,修复后还要重新回归。
真正让我停下来的,不是某个测试失败,而是一个看似更简单的问题:过去那些依赖界面操作的可见流程,现在还值得继续保留吗?与此同时,系统底层又有一些能力没有接入。一个方向是删,一个方向是加,两个动作都很容易被“完整性”这个词带偏。
我一开始以为,既然脚本越来越多、测试也越来越多,系统就应该越来越完整。后来发现,文件数量只能说明留下了多少东西,不能说明用户现在还能完成什么,也不能说明哪些东西已经失去价值。
测试通过,不等于路径仍然有效
当时的维护工作从一个普通的修复任务开始。已有测试里有不少独立运行的自检脚本,并不适合直接按常规方式一次性收集。全量测试没有按预想启动后,处理方式改成逐个执行,再分别收集结果。这样做的好处是,能够区分测试框架本身的收集问题和真正的功能问题。
这一步很重要,因为“测试没跑起来”和“功能测试失败”不是一回事。前者说明验证入口有问题,后者才说明被测行为可能有问题。如果不分开,最后很容易得到一个模糊结论:系统看起来有很多测试,但没有人真正知道它们覆盖了什么。
之后的盘点又遇到了另一层疑问。某些旧流程曾经通过可见界面完成过任务,也可能留下了相应测试。可是界面会变化,入口会迁移,真实使用方式也会变化。一个历史上能跑的流程,并不自动拥有继续维护的资格。
测试存在,只能证明过去有人为某条路径留下过证据,不能证明这条路径今天仍然值得维护。
如果不处理这个区别,后果很具体:每次系统更新,都要继续修补已经没人使用的界面路径;真正重要的底层能力反而因为没有进入清单而被遗漏。维护成本会被旧证据持续占用,系统却不一定更能解决实际问题。
表面上是补接口,其实是重新定义完整
后来用户继续追问:过去的界面可见测试是不是已经过期?还要求把没有接入的能力补齐,并做一次彻底优化。最容易误判的地方就在这里——听到“补齐能力”,就马上开始找接口;看到接口数量多,就觉得接得越多越完整。
这是一个很有诱惑力的错误捷径。接口是明确的、可计数的,接入一个就像完成了一项工作;而“这个能力是否真的需要”“是否已经有替代路径”“维护它会引入什么风险”,都不容易在短时间内体现出来。
我没有直接按接口数量扩张,是因为底层入口并不等于用户价值。有些能力已经可以由文件或草稿完成,只是没有被某个独立接口包装出来;有些界面动作看起来很完整,实际上只是旧的展示层残留;还有一些能力虽然理论上可接入,但没有稳定使用场景,接入后只会增加验证和兼容负担。
表面上我是在处理“还缺哪些接口”,其实我是在处理“完整”到底应该按什么来定义。这个定义如果不先说清,后面的每次优化都会变成凭感觉加东西。
先建立能力总表,再看差集
我最后采用的拆法,不是按文件、脚本或接口分组,而是按能力分组。每项能力至少记录几件事:真实来源是什么,是否已有稳定入口,是否已经有实际调用,能不能由现有文件或草稿完成,是否值得长期维护。
这样盘点后,系统里会出现几类不同的状态。第一类是已经有真实通道、也有使用证据的能力,它们应该优先保留并稳定验证。第二类是没有独立接口,但可以由现有草稿或文件完成的能力,它们不应被误判为“未接入”。第三类是确实没有入口、又无法由现有流程替代的能力,这才是需要评估补齐的缺口。第四类是过去留下过界面路径,但现在缺少使用证据、维护代价又高的残留,它们应该进入退役候选。
这个表的价值在于,它把几个原本混在一起的问题拆开了:有没有能力、有没有入口、有没有使用、有没有必要维护,不再用同一个“已完成”或“未完成”概括。
真正值得补的不是所有尚未出现的接口,而是现有流程无法替代、又有明确使用价值的能力缺口。
我会先看真实通道和已有调用,再看草稿能否完成,最后才看是不是需要新增接入。顺序不能反过来。要是先从接口目录开始,盘点就会被供应方的分类牵着走;从用户要完成的动作开始,才更容易发现有些缺口只是包装缺口,并不是能力缺口。
UI 残留要有退役标准
界面路径不能因为“以前能操作”就一直保留,也不能因为“现在暂时没用”就立刻删除。它需要一个比主观印象更清楚的判断标准。
我会先问它是否对应真实通道,是否还有稳定调用,是否仍然是用户完成任务所必需的入口。如果答案都是否定的,再看它是否有可替代的文件或草稿流程;如果有替代,而且旧路径只增加维护成本,就可以列入退役。只有当界面仍承载不可替代的能力,并且存在可核对的使用证据时,才值得继续投入测试和兼容工作。
这里的“退役”不是简单删除。更稳妥的做法是先从主能力清单里标记为残留,停止把它当成完整度指标,再确认有没有依赖它的测试、说明或后续调用。这样做可以避免一边删界面,一边误伤真正需要保留的底层能力。
如果不设标准,系统会出现两个相反的问题:一边是旧 UI 流程不断复活,因为它有历史测试;另一边是新接口不断增加,因为它看起来代表进步。最后维护者每天都在照顾证据,却没有把证据转化成更可靠的使用路径。
UI 退役的依据不是它看起来旧不旧,而是它是否还有不可替代的能力和可核对的使用证据。
这也是我判断“先拆 UI 残留,再分批接入能力”的原因。先把已经失去意义的路径从评估范围里拿出来,能力总表才不会被历史噪声填满;再根据价值和风险分批接入,才能知道每一次新增到底解决了哪一个缺口。
接入顺序要服从价值和风险
盘点完成以后,新增能力也不能按“谁先找到接口谁先做”的顺序推进。我会先处理无法替代、使用价值明确、且有稳定来源的能力。它们直接影响用户能否完成任务,接入后的收益比较容易验证。
其次是有价值但来源不稳定的能力。这类能力不能因为需求存在就马上承诺长期维护,而应该先记录来源、失败边界和替代方案。最后才考虑那些只有理论价值、没有实际调用证据的能力。它们可以留在候选区,但不应占用主要维护时间。
排序时还要把风险放在同一张表里。新增入口可能带来权限、依赖、兼容和验证成本;删除旧路径则可能影响仍在使用的少数场景。我的选择是先做可回退、可观察的小批量接入,并为每项能力留下“为什么接、怎样验证、失败怎么办”的记录。这样,接入不是一次性宣布完成,而是一个可以被检查的变化。
一个失败边界尤其值得记住:某项能力在静态盘点里看起来已经存在,不代表真实调用一定可达;某条关联关系看起来很近,也不代表跨版本后仍然稳定。能力总表应该记录证据等级,而不是把推断写成事实。
我更愿意把这种谨慎看成效率的一部分。没有证据的扩张,短期会让清单变长,长期却会让系统更难解释。真正省时间的做法,是让每次接入都能回答“它解决了哪个问题”,让每次退役都能回答“它为什么不再需要”。
下次我会怎么做
下次再遇到一个积累了很多脚本和测试的老系统,我会先暂停“继续加什么”的冲动,按下面的顺序重新盘点:先列出真实任务和真实通道,再把已有调用证据放进去;接着标记哪些能力已经能由文件或草稿完成;然后单独圈出无法替代的缺口;最后给旧 UI 路径做退役判断。
我会把每项能力写成一个可回答的问题:它从哪里来?现在谁在用?现有流程能不能完成?如果没有它,会卡住哪一步?维护它的成本和风险是什么?这些问题比“系统还有哪些接口”更接近真实决策。
之后,我会先处理 UI 残留,再按价值和风险分批补缺。每一批都保留使用证据、验证结果和失败边界,避免把静态存在误当成实际可用。对暂时不接入的能力,也不急着删除,而是说明它为什么被延后。
这件事让我重新意识到,一个流程成熟的标志,不是它能把所有可能的通道都接上,而是它能清楚地区分已有能力、真实缺口和历史残留。系统盘点的终点不是一张更长的接口清单,而是一套能指导取舍、验证和退役的能力地图。
工具真正改变的不是我们能加多少东西,而是我们是否愿意把判断过程留下来。下一次系统再变化时,维护者不必从“还有什么可以接”开始,而可以从证据和缺口开始。这种少依赖临场记忆的工作习惯,才是老系统优化后最值得保留的部分。