测试固定装置指的是那些写进项目、长期不变、供用例反复读取的数据。它存在的理由很单纯:如果每次运行时数据都不一样,一条用例今天通过明天失败,你就无法判断是代码变了还是数据变了。本文讲清固定装置里的身份记录该怎么组织、哪些边界样本值得固定下来,以及为什么「每次随机」会让失败变得几乎无法复盘。
为什么测试数据不能每次都重新随机
随机的诱人之处在于省事:调用一次生成,就能得到一批看起来像真的记录。问题出在排查阶段。用例失败时你需要知道它跑的是哪一条记录,而随机数据没有留下这条线索——今天失败的样本明天不会再次出现。
更隐蔽的麻烦是比较与断言。假设有一条用例断言「列表按姓名排序后的第一项是某个值」,数据一变,期望值就失效,用例红得毫无信息量。再假设缺陷只发生在姓名长度为单数的记录上,随机数据可能连续几十次运行都没有覆盖到,于是这个缺陷在测试里长期隐身。
固定装置解决的正是这两件事:可复现,以及可控覆盖。代价是需要有人认真设计一次,这份一次性的投入通常很快就回本。
固定装置该按什么来组织?
最省心的组织方式是按场景命名,而不是按字段命名。把「只填了名字没有姓氏的用户」「刚满门槛的用户」「地址与电话属于同一个国家的用户」各放成一组,用例需要什么前提就取哪一组。这样命名以后,用例与数据之间是一一对应的,读代码的人不必打开数据文件猜它是干什么用的。
| 组织方式 | 取用时的体验 | 腐化风险 |
|---|---|---|
| 按场景分组 | 用例直接说清需要什么前提 | 低,删场景时有明确边界 |
| 按国家分组 | 适合跨国表单类用例 | 中,同一场景散落多处 |
| 按字段分组 | 拼装灵活 | 高,组合爆炸且难以命名 |
| 一锅大杂烩 | 找数据靠搜索 | 最高,谁也不敢删 |
有一点值得提前决定:这些数据是共用一份,还是每个用例各持一份副本。共用省空间、改一次全生效,但一个用例的修改会影响另一个用例;各持副本互不干扰,代价是修同一个字段要改多处。数据量不大时,后者通常更省心。
随机的失败为什么几乎无法复盘?
当失败来自随机数据时,你能拿到的信息只有「这次挂了」。要复盘就得想办法把那次运行的输入找回来,而这往往已经丢失:日志里没打印完整记录,构建产物被清理了,运行环境也已经重建。
这解释了一个常被忽略的实践:随机数据适合探索与压测,固定装置适合断言与回归。两类数据的用途不同,不该互相替代。如果确实需要随机来扩大覆盖面,那就把随机取值的依据固定下来,让同一批数据可以在需要时原样重放,而不是每次运行重新抽取。这件事的意义,可复现的测试数据里讲得更细。
边界样本要准备哪些?
边界样本的价值高于常见样本,因为缺陷几乎都长在边角上。对身份记录来说,下面这几类值得各留一条并长期保留:
- 出生日期在一百年前左右的高龄记录,用来验证日期解析与年龄计算不会溢出
- 姓名特别长的记录,用来验证字段截断与界面换行
- 没有姓氏、只有一个名字的记录,用来验证必填规则是否写错
- 使用非拉丁文字的姓名,用来验证编码与检索
- 生日为闰日的记录,用来验证平年的计算口径
- 地址、电话与证件号属于同一个国家但与默认国家不同的记录,用来验证跨国分支
这几条的共同点是:它们都不会在日常运行中出现,只有人为准备才会被覆盖到。把它们固定下来以后,最好在文件里写上每条样本的用途,以免后来的人在清理时把它们当成冗余数据删掉。
固定装置该多久复核一次?
固定装置最大的优点是不变,最大的隐患也是不变。业务规则半年内改了三轮,而样本还是按最早的规则造的,这时用例依然会通过,只是它验证的东西已经和线上不是一回事了。这种失效不会报错,比一条红掉的用例危险得多。
可行的做法是给复核找一个触发点,而不是靠记性。当某个字段的校验规则、某个门槛的数值、或者某个国家相关的字段格式发生变化时,就把对应的样本一起过一遍。也可以把复核写进固定的节奏里,比如每次大版本发布前抽查一批样本,确认它们仍然代表当下的规则。复核的结论不必写成长篇报告,在数据文件旁边记一行「何时由谁核对过」通常就够了。
另外,固定装置最好有明确的归属人。一份没人负责的数据文件,在项目里存活的时间往往比它该活的时间长得多,直到某天有人发现按它写的断言毫无意义。
给开发者:让固定装置活得久一点
第一,结构与断言分离。数据文件只放数据,期望值放在用例里,并且写明它是根据数据的哪一部分得出的。这样数据一变,改动范围是可预期的。
第二,给每条记录一个稳定的编号,让用例按编号引用,而不是按数组下标或者文件里的行号。往中间插一条记录就导致所有用例错位,是最常见的一类无谓故障。
第三,把生成依据一起写下来。这批数据是用什么规则、什么时候、覆盖哪些场景生成的,写在固定装置旁边。合成出来的记录只用于测试与演示,它们不属于任何真实的个人,也不能用来冒充他人或通过任何真实身份核验;有了这条说明,后来的人也不会误把它当成真的资料。
第四,给腐化留一条检测路径。数据与期望值不一致时,用例会红;真正的问题是长期没人改的样本已经不再代表当下的业务规则。常见的做法是在数据文件上标注复核时间,或者把「这批数据覆盖了哪些规则」列成清单,规则变更时逐条核对。
第五,数据要能重新生成。一旦生成方式清楚,固定装置随时可以重建,不必担心某次误删。字段之间怎么保持自洽见身份数据一致性,跨国样本的组织方式可以对照各国身份证号长度里的形态分类。
下一步
如果你手上还没有固定装置,从最常见的三四个场景各造一组就够开始,用身份信息生成器按国家生成身份记录,导出后写进项目,并在文件里注明用途与生成依据。这些记录仅供测试使用,不要拿它们去冒充任何人。