FDE Times 数据在招 FDE 职位 863▼55 近 7 天在招职位数的变化(同口径比较):不计入本周新开始追踪的公司的职位近 7 天新增 71在招公司 181支持远程 24%美国薪资中位数 $200k招聘最多 Palantir 95
ENVI

前线部署工程师(FDE)的专业媒体

分析

客户现场跑通一次,只是一个没人能重跑的测试

谷歌SRE一书说没测过就当它坏了;真正的交接要留下测试、可度量的验收标准和运行手册,让客户团队敢改代码。

分享微博

要点速览

  • Google 的 SRE 书指出,测试通过不能证明系统可靠,测试失败却能证明系统不可靠。所以“在客户那边能跑”是很弱的证据。
  • FDE 的定制代码只为一个客户而写,常常没有测试。而以后要改这些代码的,是客户团队的人。
  • 交接时应包括:用数字定义的“可用”标准、每个行为对应的测试、每个缺陷对应的回归测试,以及附带复现用例的上游 PR。
横向的五步流程图:先用数字定义什么叫“能跑”,再逐项测试每个行为,接着把每个 bug 都变成回归测试(这一步被高亮,因为触发故障的数据已经在手边),然后定期运行生产环境测试,最后连同测试和运维手册一起移交代码。
在客户现场,合理的顺序是这样的:跑通一次只是起点。修 bug 时,触发故障的数据就在手边,所以顺手把它变成回归测试,几乎不需要额外成本。

Google 的《Site Reliability Engineering》一书中,讲可靠性测试的那一章开头有一句简短的题记:没试过的东西,就当它是坏的。几段之后,书里说得更进一步:测试通过不一定能证明系统可靠,但测试失败通常能证明系统不可靠。

在给客户发消息说“搞定了,现场已经跑起来了”之前,先想想这两句话。仔细看,在客户线上系统里顺利跑一次,不过是通过了一个测试。这个测试没人写下来,也没人能再跑一遍。

这一点之所以重要,是因为每个前线部署工程师(FDE)项目最后都要交接。Educative 讲 AI 系统 FDE 的课程里说,客户团队无法运维自己不理解的东西,也无法维护只为 FDE 设计的东西。从交接那天起,问题就从“能不能用?”变成了“改起来安不安全?”

顺利跑一次能证明什么?

看一个典型场景。你给客户写了一个脚本:从旧系统读取订单导出文件,统一日期和货币单位的格式,再把数据导入新的数据仓库。脚本在最近三天的数据上运行顺利,客户看了看仪表盘,点了点头。

这次运行证明了三件事:这三天的文件格式符合你的假设,访问权限配置正确,数据管道的每一步都没有失败。

至于某个分店导出的日期换了格式、某一行缺了客户 ID,或者下个月客户的工程师改了某个列名,会发生什么,这次运行什么也说明不了。这些情况都还没发生过,顺利运行自然无法提供任何信息。

公平地说,在真实数据上运行必不可少。PostHog 介绍 FDE 岗位的文章写道,FDE 会一直和客户一起推进,直到客户在真实数据上看到真实结果。但这是验收的条件,不是系统经得起变更的证据。

SRE 书点明了其中的差别:每个在变更前后都能通过的测试,都会减少分析人员需要考虑的不确定性。关键在于“前后”二字。现场的那次顺利运行没有“后”,因为代码改动时没人会再跑一遍。

为什么 FDE 的代码常常没有测试?

主要原因在于工作的组织方式。只为一个客户写代码,又要赶在演示前出结果,测试最容易被砍掉。

这套理由听上去很合理:代码只在一个地方用,出了问题你就在旁边,随时能修。可这套理由只在你离开之前成立。

Second File 在 Substack 上一篇讲 Field-to-Product 模式的文章里提醒了两件事:只存在于某个客户账户里的定制代码,以及成为单点故障的“英雄”工程师。没有测试的代码恰恰会把你变成这种英雄,因为只有你知道它该做什么、不该做什么。

接手代码的人来买单

《Software Engineering at Google》写道,测试软件还有一个同样重要的理由:保住修改软件的能力。对即将交接的项目来说,后果很直接。没有测试的代码仍然可以改,但对客户团队来说,每次修改都是一场赌博。

而且代价会随时间增长。同一本书说,缺陷在开发生命周期中发现得越晚,修复成本越高,很多情况下呈指数级增长。对 FDE 的代码而言,最晚的时刻就是作者已经转去别的项目,缺陷才在客户的生产环境中暴露出来。

测试还能做到书面文档很少做好的一件事。一个只检查单一行为的简短测试,能告诉客户团队你原本打算让脚本如何处理没有客户 ID 的行。它比任何 wiki 页面都可靠,因为它会运行。

交接证据是什么样的?

如果顺利跑一次还不够,那什么才够?下表把顺利运行放在第一行作为基准,再列出另外五类证据。每类证据回答的问题不同,彼此不能替代。

证据 能证明 不能证明 谁最需要
在客户现场顺利运行一次 代码在当天的数据和配置下没有出错 代码能应对新数据、新配置或新改动 演示时的客户
项目开始时约定的、用数字定义的“可用”标准 双方对成功的含义达成一致 代码是否易于维护 客户方的项目负责人
自动化测试,每个测试只验证一个行为 预期行为在每次修改后依然成立 代码满足客户的业务目标 修改代码时的客户工程师
根据现场缺陷编写的回归测试 已知缺陷不会再出现 还没人遇到过的缺陷 在各个缺陷所在位置修改代码的人
定时运行的生产环境测试 线上系统长期保持健康 某次具体改动是否破坏了某个行为 运维团队
附带复现用例的上游 PR 修复在核心产品中有了归宿 客户剩余的定制代码是否可靠 产品团队

Truong Phung 在 dev.to 上发表的一份 FDE 实践手册用一个对比概括了这种差别:顾问留下的是文档,FDE 留下的是一个运行中的系统,以及组织运维这个系统的能力。表中第一行之下的五类证据,就是这种能力,而且是客户团队可以自行检验的形式。

这份手册还建议,从一开始就把要留下的交付物写进项目定义里,包括评测、运维手册和对客户方负责人的培训,而不是拖到最后。作者提醒,没有这些,系统会在你离开后 90 天内逐渐腐化。

把现场的每个缺陷都变成测试

给老代码补齐完整的测试套件并非必需。最朴素的起点,是把现场发现的每个缺陷都记录成一个测试用例。对 FDE 来说,这几乎不增加成本,因为修缺陷时,引发缺陷的输入就在手边。

回到那个订单脚本。假设第二周某个分店发来的文件里,日期按日-月-年书写,而脚本把它读成了月-日-年。

你修好了它,再多花十分钟写一个测试,用的就是那三行数据,检查日期是否被正确解析。从此以后,任何客户工程师改动日期解析函数时,只要再次弄坏这个场景,测试马上就会失败。

下一步是把值得保留的东西移进产品。Field-to-Product 那篇文章用一句话概括了泛化这一步:把抽象和测试推到上游,淘汰本地补丁。

上面的日期解析缺陷就是很好的候选。如果产品本身有导入功能,这个测试就应该放进产品仓库,而不只是留在某个客户的定制目录里。

决定成败的是时机。这些工作大多必须在项目第一周就开始,而不是最后一周,原因在于晚写的测试实际上在做什么。

最后一周写的测试在检查什么?

最常见的错误是以为有了生产环境检查就够了。生产环境测试必不可少,但它只能说明系统依然健康,无法告诉你上一次改动破坏了哪个行为。

更隐蔽的错误是把测试都挤到最后一周。这时写的测试往往只是记录代码当前的行为。freeCodeCamp 的一篇教程说得很明白:这类测试并不能说明现有行为是正确的;作者写道,自己只是在记录行为,并不假装它是对的。

重构遗留代码时,这种技巧很有用。但如果交出去的测试套件全是这种测试,你就是把自己的错误冻结起来,当作预期行为交给客户团队。在你还在问客户“没有 ID 的行该怎么处理?”时就写下的测试,记录的是意图,而不是现状。

另一个陷阱是写一个巨大的测试,从输入文件一路检查到仪表盘。它一旦变红,客户工程师根本看不出是哪个行为坏了。最后一个陷阱是在现场修了缺陷却不留测试,还把修复一直放在定制分支里。缺陷可能卷土重来,核心产品也永远不会知道它的存在。

招聘经理想看到什么?

在简历上,“为客户 X 部署了一条数据管道”的分量不比一次顺利运行更重。“交接时为现场发现的每个缺陷都附上了回归测试;之后的修复由客户团队独立上线”说明的要多得多。

面试时,要准备好讲清一个具体缺陷:你是怎么复现的,测试长什么样,这个测试现在放在哪个仓库里。

现场顺利运行能帮你拿到验收签字。交接做得好不好,要等到客户团队第一次修改代码、而且不用打电话找你的时候,才见分晓。

这篇文章对你有帮助吗?

7 个信源
路线图上的下一篇 · 阶段 6: 价值度量在越南工作,合同类型决定谁来报税在越南没有实体的外国公司只能通过 EOR 或承包商形式雇你,7 月起的新个税法也改变了算法。