分享在正式发布工具前必须自己实际操作的经验,强调这种方法能发现自动化测试遗漏的交互类 Bug。
错误发生得很早,在我养成正确习惯之前。我构建了一个小工具的第一个版本,手动运行了几遍显而易见的路径,看着它表现符合预期,然后就发布了。我没有之后坐下来真正使用它去完成它原本要解决的任务。我测试过它。但我没有真正用过它。
这个区别在大约一周后显现了出来。一个单独使用时工作正常的设置,却与我之前在流程中选择的一个默认值产生了冲突。这个冲突只有在你于同一个会话中按特定的顺序同时触碰这两项时才会出现——这恰好正是真实用户会做的事,也恰好正是快速手工测试不会做的事。有人反馈了一个看起来像 bug 的行为,因为它确实是。我一开始无法复现,因为复现它意味着要像真实用户一样使用工具,从头到尾、在一定的时间压力下,而不是逐个戳各个功能。
这就是规则改变的时刻。从那以后,没有任何东西从这个工作室发出,直到我自己真实地使用过它,用于它存在的真实工作,而不是该工作的演示版本。
我仍然记得一旦找到问题,实际的修复有多简单——仅仅几行代码,改起来花不了几分钟。更花时间的是认识到真正的问题不在于那个特定的 bug,而在于让它通过的流程。因为下一个 bug 也会通过同样的缺口,因为这个缺口根本不是关于那个设置。它反映的是我确认了各个部分工作正常,却从未确认整个东西在真实、略显不耐烦的使用场景下工作正常。
这与测试不一样,我想明确说明这个区别,因为人们很容易自欺欺人地认为自己在做其中一件事,实际上却在做另一件。测试就是过一遍检查清单:这个按钮工作吗?这个字段验证吗?这个导出能生成文件吗?使用工具是把它放在你和一个你真实需要完成的任务之间,然后承受它带来的任何摩擦。
Git Dojo 的存在正是因为我想要一种真正练习 git 命令的方式,而不是每次都去查。所以在我说它完成之前,我在自己身上用真实的终端会话完整地运行了真实的课程——与我做实际项目工作用的同一套,而不是沙盒演示账户。就是在那时我发现,我设计得想要令人鼓舞的一个关卡,当你已经通过前面的关卡两次后,实际上感觉是令人贬低的。一个检查清单会确认这个关卡完全按设计工作。但使用它告诉我设计本身有问题。
OhNine 最清楚地说明了这一点,因为整个概念只有在真实压力下才能证明自己。一个使用追踪工具如果你仅仅看一眼数字然后继续,就没什么用。我必须实际运行重任务会话,让它坐在菜单栏里,像我自然会忽视任何小通知那样去忽视它(当时我正深入工作),看看警报是否真的能突破那种忽视。第一个版本没能做到。阈值在我已经深入任务、不想停下来的点才触发,所以警报虽然存在,但对任何人都没有真正帮助。这只有在你是那种容易陷入工作、忘记检查的人时才会显现——这正是工具的目标用户。但检查清单测试永远不会被工作吸收。
我想诚实地说清楚这个习惯的边界在哪里,因为自己进行 dogfooding 确实有真实的局限,假装没有只会是另一种形式的不诚实。我只是一个用户,有自己的一套工作方式、用的操作系统多半相同、对终端的熟悉度远超明确购买 Git Dojo 的大多数人。以一个不再是初学者的身份使用初学者工具,能告诉我功能是否正常,但几乎说不出语气是否恰当、节奏对实际学习的人是否感觉对、我认为理所当然的说明对第一次接触这个概念的人是否容易理解。
这就是为什么自己使用必须是底线,而不是全部。它能捕捉只在真实、持续使用下才会出现的 bug——检查清单在结构上永远发现不了的那种,因为清单的设计者已经知道工具应该怎样工作。它不能替代听取从未见过工具、不知道快捷方式、会踩到你早就习惯了因此不再注意的确切措辞的人的反馈。对于任何面向技术水平低于我的人的工具,我仍然需要那种反馈,我已经学会了不把自己舒适的重复使用当作它的替代品。
还有一个只在足够反复使用后才会出现的特殊盲点:我停止把自己做的工具视为新鲜事物。用了自己做的东西三四次真实工作后,我已经知道每个快捷方式、每个菜单应该更浅的地方、每个标签的含义(仅因我知道它代表什么)。这种熟悉感恰好是让我的使用在某个阶段后变得不可靠的原因。它只能证明工具对已经理解它的人有效——而这是我从来不需要证明的唯一事情。所以真正的习惯不是"用一次然后算了",而是"早点用,趁熟悉感还没有形成,然后让完全陌生的人在宣布完成前把关"。
最直接的效果是上线后出问题的东西更少,因为曾经作为用户反馈浮现的 bug,现在在我自己使用时就浮现了,在任何其他人看到之前。这听起来像是显而易见的事后之言,但这需要我真的经历过反面——发布没有真正被使用过的东西,看着真实用户踩到坑——才能真正让这条规则坚持下去,而不仅仅是停留在"我应该这样做"的想法。
不太显眼的效果是在进度上。在发布前正确使用工具需要真正的时间投入,比快速跑一遍手工测试花的时间多,因为你没法像跑检查清单那样仓促地完成真实工作会话。晚上和周末的时间是有限的,这条规则意味着有些东西需要更长时间才能发布,相比之下如果我直接从"它能用"跳到"上线了"。我已经接受了这个权衡。一个晚点发布但经过真实使用的工具,比按时发布但第一周就需要修复的工具值得多,因为修复的代价远超过延期。
它也改变了我对自己 bug 报告的解读方式,或者说对那些通过这套流程的工具所收到的几乎没有的 bug 报告。当某样东西发布前真实被使用过,之后收到的大多数反馈都像是抛光请求,而不是"这坏了"的报告。这个转变——从 bug 报告到功能请求——比任何内部审查更能说明这个习惯是否真的有效。
还有一件我没有预见到的事情改变了:工具范围的规划方式。一旦你承诺发布前真实使用某样东西,那些听起来在纸上不错但你个人永远不会想坐着用的功能会被更早地砍掉,因为你是第一个必须用它的人。一些规划时看起来合理的想法,一旦真正用起来就活不过一个工作会话,不是因为技术上坏了,而是因为你会意识到没人会费力去用它。这是比收集用户投诉更便宜的地方来淘汰一个坏想法。
规则很简单:在任何东西离开这个工作室前,我必须用它完成它存在的真实任务,而不仅仅是验证各个部分能工作。这一个习惯能捕捉整个类别的问题——那些只在真实、持续的使用中才会出现的问题,检查清单在结构上永远无法发现,因为它只能测试清单设计者已经预期的东西。它不能替代听取与我完全不同的人的意见,我试图对这个局限保持诚实,而不是假装我自己的使用能代表所有人。但作为任何东西发布的前置条件,这个单一习惯做得最多来缩小"它能用"和"实际使用它的人能用"之间的差距。