1. 测试数据生成这件事,为什么值得单独拎出来聊
做开发、做测试的人都有一个共识:功能代码写完了只是开始,真正折磨人的是“拿什么数据来跑”。一个订单系统,你写完了下单逻辑,想验证并发扣库存有没有问题,结果手头只有三条手工录入的假数据,连分页都翻不满一页,更别提压测了。一个用户画像模块,你想验证标签命中率,结果数据库里只有“张三、李四、王五”三个名字,性别全是男,年龄全是 18 岁,这种数据跑出来的结果没有任何参考价值。
所以测试数据生成从来不是“随便造几条”的小事,它直接决定了你的测试覆盖率、缺陷发现率,以及上线之后会不会被真实数据打脸。我见过太多团队在项目后期才想起来补数据,临时写脚本、临时改字段,最后数据之间外键对不上,跑一半报错,排查半天发现是造数据的人把用户 ID 和订单 ID 搞混了。
这个内容要聊的,就是测试数据生成这件事到底有多少种做法,六款常用工具各自适合什么场景,以及现在用 AI 来生成测试数据到底靠不靠谱、怎么落地。不管你是刚入行的测试新人,还是带了几年团队的老手,只要你还在一线跟数据打交道,这篇内容都能让你少走一些弯路。我会把每款工具的适用边界、参数配置、踩坑点都摊开讲,最后重点说说 AI 生成这条路子怎么用才不翻车。
2. 六款主流测试数据生成工具横向拆解
2.1 工具选型之前,先搞清楚你的数据需求属于哪一类
在推荐工具之前,我必须先泼一盆冷水:没有一款工具能通吃所有场景。你在选工具之前,先问自己三个问题。
第一个问题:你要的是结构化数据还是非结构化数据?结构化就是数据库表里的行和列,字段类型明确,有主外键约束;非结构化就是文本、图片、日志、JSON 嵌套文档这类,格式松散但内容有语义要求。
第二个问题:你的数据量级是百条级、万条级还是百万级?百条级手工写都行,万条级需要脚本或工具,百万级就得考虑生成效率和存储开销了。
第三个问题:数据之间有没有关联约束?比如订单表里的 user_id 必须能在用户表里找到,商品价格必须大于 0,创建时间不能晚于支付时间。有约束的数据,生成难度直接上一个台阶。
把这三个问题想清楚,你基本就能锁定工具范围了。下面这六款是我在实际项目里反复用过的,各有各的脾气。
2.2 六款工具的能力对比与适用场景
先上一张对比表,把核心差异摆出来,后面再逐个展开。
| 工具类型 | 代表方案 | 数据关联性 | 学习成本 | 适合量级 | 典型场景 |
|---|---|---|---|---|---|
| 在线数据生成器 | 某在线 Mock 平台 | 弱 | 极低 | 百条级 | 前端联调、接口 Mock |
| 命令行生成工具 | 某 Faker 类库 | 中 | 低 | 万条级 | 单元测试、数据库填充 |
| 数据库内置函数 | SQL 随机函数 | 弱 | 低 | 万条级 | 快速造简单表数据 |
| 专用数据工厂 | 某数据构造框架 | 强 | 中高 | 百万级 | 集成测试、压测 |
| 录制回放工具 | 流量录制方案 | 强 | 中 | 取决于流量 | 回归测试、真实场景复现 |
| 脚本自研 | Python/Java 脚本 | 完全可控 | 中 | 任意 | 复杂业务约束场景 |
这张表不是让你背下来的,是让你在选型时有个参照。我逐个说一下实际使用中的感受。
在线数据生成器最大的优势是快,打开网页,选字段类型,点生成,复制粘贴就能用。但它的问题也很明显:数据之间没有关联,生成的 100 个用户和 100 个订单,user_id 对不上。所以它只适合前端联调阶段,后端逻辑测试千万别用它。
命令行生成工具是我用得最多的。以 Python 的 Faker 类库为例,一行代码就能生成姓名、地址、邮箱、手机号,而且支持多语言。它的关联性可以通过代码控制,比如先生成用户列表,再从用户列表里随机取 ID 生成订单。缺点是数据量大了之后内存占用高,百万级需要分批写入。
数据库内置函数适合应急。比如 MySQL 的 RAND() 配合 INSERT INTO SELECT,几行 SQL 就能造出几万条数据。但它生成的数据太“假”了,姓名全是“user_12345”,地址全是“address_1”,只能用来测分页和基本查询,业务逻辑测试指望不上。
专用数据工厂是给专业测试团队用的,支持定义数据模型、字段规则、关联关系,还能控制生成速率和分布。学习曲线陡,但一旦配好,复用性极强。我之前在一个金融项目里用它造了 50 万条交易流水,关联了用户、账户、商户三张表,跑批测试一次通过。
录制回放工具的思路不一样,它不是“造”数据,而是“抄”数据。把生产环境的流量录下来,脱敏之后在测试环境回放。优点是数据绝对真实,缺点是依赖生产流量,而且脱敏不彻底会有合规风险。
脚本自研是最灵活的,也是最累的。业务约束越复杂,自研脚本的价值越大。比如“VIP 用户的订单金额必须是普通用户的 1.5 倍以上,且订单创建时间必须在工作日 9 点到 18 点之间”,这种规则用现成工具很难配,但写个 Python 脚本就是几行判断的事。
提示:选工具的时候不要追求“一步到位”,先用最简单的方案把流程跑通,遇到瓶颈再换。我见过太多人一上来就搭数据工厂,结果配了两天规则,业务需求变了,全白干。
3. 用 AI 生成测试数据,到底怎么落地
3.1 AI 生成数据的核心逻辑:从“规则驱动”到“语义驱动”
传统工具生成数据的逻辑是规则驱动:你告诉它字段类型是字符串,长度 10,它就随机拼 10 个字符。至于这 10 个字符是“张三”还是“asdfghjkl”,它不关心。
AI 生成数据的逻辑是语义驱动:你告诉它“生成一条用户投诉记录,投诉内容是物流太慢,情绪偏负面”,它会生成一段像人写的投诉文本,而不是随机字符串。这是本质区别。
这个区别带来的价值在于:当你的测试需要“像真实业务数据”而不是“像数据库字段”时,AI 的优势就出来了。比如测试一个情感分析模块,你用 Faker 生成的“用户评论”全是乱码,模型根本跑不出结果;但用 AI 生成的评论有褒有贬,有长有短,测试才有意义。
AI 生成测试数据目前主要有三种落地方式。
第一种是直接调用大模型 API,把字段说明和约束写成提示词,让模型返回 JSON 格式的数据。这种方式最灵活,但要注意控制返回格式,否则模型可能给你返回一段散文。
第二种是用 AI 辅助写生成脚本。你把业务规则描述给 AI,让它帮你写 Python 脚本,你审核后运行。这种方式适合规则复杂但数据格式固定的场景,AI 帮你省的是写代码的时间,不是生成数据的时间。
第三种是用 AI 做数据增强。你已经有了一批真实数据(比如 1000 条脱敏后的用户反馈),让 AI 基于这些数据生成更多相似的变体,扩充测试集。这种方式在算法测试里特别常见。
3.2 提示词怎么写,才能让 AI 吐出可用的数据
这是实操中最关键的一步。我见过很多人写提示词就一句话:“生成 100 条用户数据”,结果 AI 返回一堆格式不统一的文本,根本没法解析。
正确的做法是把 AI 当成一个刚入职的实习生,你要把字段名、类型、取值范围、格式要求、关联关系全部说清楚。下面是我常用的提示词模板,你可以直接抄。
你是一个测试数据生成器。请生成 50 条用户表数据,以 JSON 数组格式返回,不要有任何额外说明文字。 字段要求: - user_id:整数,从 10001 开始递增 - user_name:中文姓名,2-3 个字 - age:整数,18-65 之间 - gender:枚举值,只能是 "男" 或 "女" - city:中国一线城市名称 - register_time:日期时间,格式 YYYY-MM-DD HH:mm:ss,范围在 2023-01-01 到 2024-12-31 之间 - vip_level:整数,0-3 之间,0 表示非会员 约束: - 年龄大于 60 的用户,vip_level 不能为 3 - register_time 必须按时间先后顺序排列这个提示词的关键点在于:明确输出格式(JSON 数组)、明确字段类型和范围、明确约束条件、明确不要额外文字。实测下来,这样写提示词,AI 返回的数据 90% 以上可以直接用,剩下 10% 可能需要微调。
还有一个技巧:分批生成。不要一次性让 AI 生成 1000 条,它可能会偷懒或者格式错乱。每次生成 50 到 100 条,多跑几次,然后合并。这样既保证了质量,也方便排查问题。
注意:AI 生成的数据一定要做格式校验。我踩过的坑是,AI 有时候会把数字写成字符串(比如 "age": "25" 而不是 "age": 25),如果你的代码直接入库,类型不匹配就会报错。所以生成之后跑一遍校验脚本,把不符合类型的数据过滤掉或者修正。
3.3 AI 生成数据的边界:哪些场景千万别用
AI 不是万能的,有些场景用它就是给自己找麻烦。
第一,涉及精确计算的场景。比如你要生成一批订单数据,要求“订单总金额 = 商品单价 × 数量 + 运费 - 优惠券”,这种精确的数学关系,AI 经常算错。它可能会给你一个总金额 100,但单价 30、数量 3、运费 10、优惠券 5,算下来对不上。这种场景还是用脚本生成,AI 只负责生成商品名称、用户备注这类文本字段。
第二,数据量极大的场景。百万级数据用 AI 生成,成本高、速度慢,而且没必要。这种场景用 Faker 类库或者数据工厂,AI 只用来生成其中需要语义的字段,比如商品描述、用户评论。
第三,有严格合规要求的场景。AI 生成的数据可能包含训练数据里的真实信息片段,虽然概率很低,但一旦出现就是事故。所以涉及个人隐私、商业机密的测试数据,要么用脱敏后的真实数据,要么用规则工具生成,不要用 AI。
第四,需要精确控制数据分布的场景。比如你要测试一个推荐算法,要求用户年龄符合正态分布,性别比例 6:4,地域分布按真实城市人口比例。这种精确的分布控制,AI 做不到,必须用脚本按概率生成。
我个人的经验是:AI 负责“像”,脚本负责“准”。两者结合,才是最高效的方案。
4. 从零搭建一套可复用的测试数据生成流程
4.1 第一步:定义数据模型和约束规则
不管你用什么工具,第一步永远是把数据模型写清楚。我习惯用一个 YAML 文件来描述,因为 YAML 比 JSON 好写注释,比 Excel 好做版本管理。
table: user fields: - name: user_id type: integer start: 10001 step: 1 - name: user_name type: string generator: ai prompt: "中文姓名,2-3个字" - name: age type: integer min: 18 max: 65 - name: gender type: enum values: ["男", "女"] weights: [0.55, 0.45] - name: city type: string generator: faker faker_type: city - name: register_time type: datetime start: "2023-01-01 00:00:00" end: "2024-12-31 23:59:59" order: ascending constraints: - "age > 60 => vip_level != 3"这个文件的好处是:人和机器都能读。人看了一目了然,机器可以直接解析成生成逻辑。字段的 generator 标记了用哪种方式生成,ai 走 AI 接口,faker 走本地类库,integer 走随机数。约束条件单独列出来,方便校验。
4.2 第二步:分层生成,先主表后从表
数据关联是造数据最容易翻车的地方。我的做法是分层生成:先做主表(用户表),再做从表(订单表),从表的外键从主表的主键里随机取。
具体操作上,先生成用户列表,存到一个临时文件或者内存里。然后生成订单的时候,每生成一条订单,就从用户列表里随机选一个 user_id 填进去。这样保证订单的 user_id 一定能在用户表里找到。
如果关联层级更深,比如用户 → 订单 → 订单详情 → 商品,那就一层一层往下生成。每一层都依赖上一层的输出。这种方式的缺点是内存占用高,但数据量在百万级以内都可以接受。超过百万级,就要考虑用数据库临时表来存中间结果。
提示:生成关联数据的时候,记得控制关联比例。比如不是每个用户都有订单,你可以设定 70% 的用户有 1-5 条订单,30% 的用户没有订单。这样更接近真实业务场景,也能测试到“无订单用户”的分支逻辑。
4.3 第三步:数据校验与清洗
生成完数据不要直接入库,先跑一遍校验。校验分三层。
第一层是格式校验:字段类型对不对,日期格式对不对,枚举值在不在范围内。这一层用 JSON Schema 或者自定义校验脚本都能做。
第二层是业务校验:约束条件有没有被违反。比如“年龄大于 60 的用户 vip_level 不能为 3”,这种规则要单独写校验逻辑。
第三层是关联校验:外键能不能找到对应的主键,关联数量对不对。比如订单表里的 user_id 是不是都在用户表里存在。
校验不通过的数据,要么丢弃,要么修正。我一般选择丢弃并记录日志,因为修正的成本可能比重新生成还高。但如果丢弃率超过 10%,说明生成规则有问题,需要调整提示词或者参数。
4.4 第四步:入库与性能优化
数据校验通过之后,就是入库。入库的性能优化有几个关键点。
批量插入比单条插入快得多。MySQL 的 INSERT INTO ... VALUES (...), (...), ... 一次插 1000 条,比循环插 1000 次快几十倍。但要注意 max_allowed_packet 参数,一次插太多可能会超限。
关闭索引和约束再插入,插完再重建。对于百万级数据,这个优化能把入库时间从几小时缩短到几分钟。但要注意,关闭约束期间不能有脏数据写入,否则重建索引会失败。
分批提交,每 1000 条或 5000 条提交一次事务。事务太大容易锁表,太小又频繁 IO。我一般用 2000 条一批,实测下来比较均衡。
# 批量入库示例 import pymysql conn = pymysql.connect(host='localhost', user='test', password='test', database='test_db') cursor = conn.cursor() batch_size = 2000 for i in range(0, len(data), batch_size): batch = data[i:i+batch_size] sql = "INSERT INTO user (user_id, user_name, age, gender, city) VALUES (%s, %s, %s, %s, %s)" cursor.executemany(sql, batch) conn.commit() print(f"已插入 {min(i+batch_size, len(data))} 条") cursor.close() conn.close()这段代码是我常用的模板,改一下 SQL 和字段就能复用。注意 executemany 的参数格式是列表套元组,每个元组对应一条记录。
5. 实操中踩过的坑与排查技巧
5.1 数据生成常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| AI 返回格式不是 JSON | 提示词没强调格式 | 检查提示词是否明确要求 JSON | 在提示词开头加“只返回 JSON,不要任何说明文字” |
| 生成的数据外键对不上 | 关联逻辑没做或做错了 | 抽样检查从表外键是否在主表中 | 分层生成,从表外键从主表主键池中取 |
| 入库速度极慢 | 单条插入或索引过多 | 查看 SQL 执行计划 | 批量插入,临时关闭索引 |
| 数据分布不均匀 | 随机函数有偏或权重没配 | 统计各枚举值的数量 | 用加权随机代替均匀随机 |
| AI 生成的数据有重复 | 提示词没要求唯一性 | 去重统计 | 提示词加“所有 user_name 不重复” |
| 日期顺序错乱 | 生成时没排序 | 检查日期字段是否按序 | 生成后按日期排序再入库 |
| 内存溢出 | 一次性加载太多数据 | 监控内存使用 | 分批生成、分批入库 |
这张表里的问题,我几乎每一个都遇到过。重点说几个印象深刻的。
AI 返回格式问题是最常见的。有一次我让 AI 生成 100 条商品数据,提示词里写了“返回 JSON”,结果它返回了一个 Markdown 代码块,里面才是 JSON。我的解析脚本直接报错。后来我在提示词里加了一句“不要用 Markdown 代码块包裹,直接返回纯 JSON 文本”,问题就解决了。
外键对不上这个问题,根源在于生成顺序。如果你先生成订单再生成用户,订单里的 user_id 就是瞎编的,用户表里根本没有。所以一定要先主后从,这个顺序不能乱。
数据分布不均匀是个隐蔽的坑。比如你用随机数生成性别,理论上男女各 50%,但实际跑出来可能 70% 是男。这是因为随机函数的分布特性,数据量小的时候偏差更明显。解决办法是用加权随机,或者生成后做一次平衡调整。
5.2 几个让我省下大量时间的实操技巧
技巧一:用固定随机种子。生成数据的时候,如果每次结果都不一样,排查问题就很麻烦。设置一个固定的随机种子,每次生成的数据序列完全一致,方便复现和对比。Python 的 random.seed(42) 或者 numpy 的 np.random.seed(42) 都能做到。
技巧二:生成数据的同时生成校验报告。不要等入库之后才发现问题,生成完立刻跑校验,输出一份报告:总条数、各字段空值率、枚举值分布、约束违反数量。这份报告就是你判断数据质量的依据。
技巧三:把生成配置和生成脚本分开。配置(字段规则、约束条件)放在 YAML 或 JSON 文件里,脚本只负责读取配置并执行。这样业务规则变了,改配置文件就行,不用动代码。团队协作的时候,测试人员可以自己改配置,不需要开发介入。
技巧四:AI 生成的数据一定要人工抽检。不要因为 AI 说“已生成 100 条”就信了。随机抽 10 条出来看看,姓名是不是像人名,地址是不是像地址,评论是不是像人话。我抽检的时候发现过 AI 生成的“中文姓名”里混进了英文名,还有一次生成的“城市”里出现了“纽约”。抽检花不了几分钟,但能避免大问题。
提示:如果你用 AI 生成的数据做自动化测试的输入,建议把生成结果缓存起来。同一个测试用例每次跑都用同一批数据,避免因为数据变化导致测试结果不稳定。缓存文件用版本号管理,需要新数据的时候再重新生成。
6. 关于测试数据生成,我个人的几点体会
做了这么多年测试和数据相关工作,我最大的体会是:测试数据生成不是技术问题,是意识问题。很多团队不是不会造数据,是根本没把造数据当回事。等到测试跑不起来、缺陷漏到线上,才回头补课。
六款工具也好,AI 也好,都只是手段。核心是你得清楚你的测试需要什么样的数据。是只需要字段格式对,还是需要业务语义对?是只需要单表数据,还是需要多表关联?是只需要百条级,还是需要百万级?想清楚这些,工具选型就是水到渠成的事。
AI 生成测试数据这条路,我的建议是先用起来,再优化。不要一上来就追求完美提示词,先跑通一个简单场景,比如生成用户评论,看看效果。效果好了再扩展到其他字段,效果不好就调整提示词或者换回规则工具。AI 不是替代传统工具,是补充传统工具覆盖不到的场景。
最后分享一个小技巧:把你常用的提示词和生成脚本存成一个模板库。下次遇到类似场景,直接改字段名和范围就能用,不用从头写。我自己的模板库里存了二十多个提示词模板,覆盖用户、订单、商品、日志、评论等常见场景,新项目直接复用,效率提升非常明显。
这个方向后续还可以往数据血缘追踪上扩展,就是记录每一条测试数据是怎么生成的、经过了哪些处理、被哪些测试用例使用了。这样当测试结果异常时,可以快速定位是数据问题还是代码问题。我现在正在尝试用元数据管理的方式来做这件事,等跑通了再单独写一篇分享。