ChatGPT造数实战:用提示词高效生成测试数据

📅 发布时间:2026/9/8 1:39:38
ChatGPT造数实战:用提示词高效生成测试数据
有人可能觉得我在夸张但说真的第一次用ChatGPT批量生成测试数据的时候我盯着屏幕愣了好几秒——平时要吭哧吭哧写半天的造数脚本它几十秒就给了一套结构完整、覆盖场景还挺像样的数据。干测试这行的人应该都懂测试数据永远是那个不起眼但卡脖子的环节联调缺数据测试环境空荡荡性能测试要大文件边界值永远凑不齐。这篇文章就围绕ChatGPT生成测试数据这件事把我这几个月实际踩过的坑、验证过的方法、沉淀下来的提示词模板全部摊开讲。不管你是测试工程师、开发自测、还是刚入门想偷懒的新人按着文章里的思路走造数据这件事的效率能翻好几倍。1. 造数据这件事凭什么让ChatGPT来干1.1 手工造数据的日常有多痛苦先说说我自己的真实经历。之前在一个电商项目里做接口测试订单模块联调的时候开发跑过来跟我说测试环境order表给我造200条数据要覆盖已支付、待发货、已发货、已完成、已取消这几种状态还得有半年前的旧订单。我当时第一反应是打开Navicat手动复制粘贴INSERT语句改字段值。一条两条还行200条光改时间戳就能改到怀疑人生。更烦的是你以为自己覆盖了所有场景测试跑到一半发现漏了金额为0的订单、备注超长的情况又得回头补数据。这种活干过的人都懂属于典型的不创造价值但又不得不做的重复劳动。后来我也试过写存储过程、写Python脚本用Faker库生成确实能解决问题但每次新项目、新表结构都要重新写一遍脚本维护成本不低。而且Faker生成的数据偏随机缺少业务逻辑的约束比如用户状态和订单状态之间的关联脚本里得一个个字段去写规则。1.2 ChatGPT适合干这活的底层原因ChatGPT能解决这个问题核心在于三点。第一它懂自然语言约束。生成50条订单数据状态要覆盖5种时间要分布在上个月——这种话你跟脚本说它听不懂你得翻译成代码逻辑但跟ChatGPT说它直接就理解了。第二它能把业务规则翻译成数据。你告诉它已取消的订单必须有取消原因已发货的订单必须要有物流单号它会自觉地在每一条数据里遵守这个逻辑。这其实就是把隐性的测试设计思路具象化。第三它的输出格式高度可控。JSON、SQL、CSV、Markdown表格你说要什么格式就是什么格式直接省掉了大量格式化处理的工作。说到底ChatGPT在这个场景里扮演的角色不是一个数据生成器而是一个懂业务规则的测试数据设计助理。你出规格它出数据中间那段最耗时的人工编辑工作被彻底压缩了。2. 提示词就是你的数据规格说明书2.1 先学会要结构再学会要内容用好ChatGPT生成测试数据90%的功夫在写提示词。而且我建议你脑子里有一个认知提示词不是在跟AI聊天而是在写数据规格说明书。最基础的做法是把表结构或者字段说明直接丢给它。比如我第一次用的提示词是这样的你是一个资深测试工程师。请帮我生成用户表测试数据表结构如下 id, username, email, phone, status, created_at 要求 1. 生成20条记录 2. username用中英文混合的常见用户名 3. email符合邮箱格式 4. status包含正常、禁用、待激活三种状态 5. created_at分布在最近一年内 6. 用Markdown表格输出这一段看起来简单但有几个容易被忽略的细节。第一我给每一类字段都指定了明确的生成规则而不是笼统地说按实际数据生成不然它会默认给你一堆admin、test之类的无聊数据。第二我对status字段做了状态枚举限制确保覆盖真实业务中存在的状态类型而不是随机发挥。第三我明确指定了输出格式避免它在数据前后加一堆解释文字增加我后期清洗的成本。实测下来的体验是ChatGPT对格式指令的遵从度很高说好只要表格就只要表格说好20条就20条。反而是那些没写清楚约束的字段最容易出幺蛾子。2.2 用约束条件把数据质量钉死有了基础体验之后我开始试着在提示词里加硬性约束这一步是把数据质量从能看提升到能用的关键。我常用的约束手段有这么几类枚举值约束明确列出允许的取值比如order_status只能是 pending、paid、shipped、completed、cancelled关联约束指定字段之间的逻辑关系比如已取消的订单cancel_reason字段不能为空格式约束对手机号、邮箱、身份证等字段指定正则级别的要求分布约束规定数据的时间分布、金额区间、长度边界举个例子我后来生成订单数据用的提示词是这样的生成100条orders表数据表结构如下 order_id, user_id, order_amount, order_status, pay_time, ship_time, cancel_reason 约束条件 1. order_amount范围在0.01到9999.99之间保留两位小数其中必须有5条金额为0 2. order_status覆盖 pending(20%)、paid(20%)、shipped(20%)、completed(30%)、cancelled(10%) 3. pay_time必须在order_status变为paid之后才存在 4. ship_time只在status为shipped或completed时才有值 5. 状态为cancelled的记录cancel_reason必须是用户取消、超时未支付、库存不足三者之一 6. 输出为CSV格式不要表头以外的任何内容你注意第2条我特意把比例也写进去了。为什么要写比例因为如果你只说覆盖五种状态它大概率会给你平均分配每种20条但实际业务里已完成的订单占比通常远高于已取消。既然做测试数据分布越接近真实接口性能压测和前端分页展示的效果就越可信。第3、4条是真正的关键。我发现ChatGPT有很强的惯性生成问题你给了它ship_time这个字段它就每行都填完全不管这个订单是不是压根没发货。所以这种字段间的条件依赖必须在提示词里明确写清楚不然后续清洗数据的时候心态会崩。2.3 场景化生成让数据自带业务逻辑光有格式正确的数据还不够测试要覆盖的是场景不是字段。所以后面我开始尝试直接在提示词里定义业务场景让ChatGPT按场景批量产出数据。比如做接口测试时我不再要求生成50条订单数据而是改成请帮我生成一组完整的订单接口测试用例数据覆盖以下场景 1. 正常下单且库存充足 2. 正常下单但使用了已过期的优惠券 3. 下单时商品库存不足 4. 下单时用户余额不足 5. 订单金额为0的边界场景 6. 下单请求里缺少必填字段 7. 备注字段长度超过500字 8. 同一用户并发提交相同订单 每个场景输出对应的JSON请求体用json代码块包裹场景编号做注释这个做法的好处是你生成的已经不只是数据而是带测试意图的数据。之前你说库存不足这个场景我得手动把库存字段改到低于购买数量现在我只要把场景描述清楚ChatGPT会自动把库存数、下单数量设置成一个能体现矛盾关系的组合。这里分享一个很实用的技巧场景化生成时给它一个负面清单。也就是明确告诉它不要生成什么。比如所有场景都不允许出现用户名为空的记录所有金额字段不允许出现负数金额为0的边界用例除外。这么做能有效压制它对某些字段的自由发挥让生成结果更贴近真实业务的取值空间。3. 三张实战配方JSON、SQL、CSV一次到位3.1 接口测试的JSON报文数据接口联调时最烦的是什么不是没有数据是报文结构对不上。字段少一个、类型不对、嵌套层级错了接口直接报400。用ChatGPT生成JSON最大的价值在于它能把嵌套结构一次做对。我之前对接一个支付回调接口报文是多层嵌套的生成支付回调接口的测试报文结构如下 { request_id: 字符串, merchant: { merchant_id: 字符串, notify_url: URL格式 }, order: { order_id: 字符串, amount: 数字单位分, currency: CNY/USD/HKD枚举, items: [商品名数组, 至少1个元素] }, sign: 32位小写MD5字符串 } 请生成5个正常报文和5个异常报文。 异常报文要求覆盖sign为空、amount为负数、items为空数组、currency为非法值、缺少request_id。 输出为JSON数组用代码块包裹。实际用下来ChatGPT对这种嵌套JSON结构的还原度非常高基本不用我再手工调整层级。而且它生成的异常报文是那种看起来像真的但实际有问题的数据——比如sign填了一串abc123amount填了-50——这种数据比简单粗暴地传空值更有测试价值因为能测出接口对非法输入的校验逻辑到底严不严。唯一要注意的是字段命名风格。如果接口是下划线命名法你必须在提示词里写清楚所有字段使用snake_case否则它会默认给你用驼峰风格到时候还得批量替换。3.2 数据库初始化SQL脚本本地开发、测试环境初始化最需要的就是一批能直接往里灌的SQL。我之前踩过一个坑让ChatGPT生成INSERT语句结果它给的外键user_id值跟我users表里的id对不上一执行全是外键约束冲突。后来我的提示词改成这样问题才算解决users表已有数据的id范围为1到50。 请根据以下表结构生成60条order表的INSERT语句 CREATE TABLE orders ( id INT PRIMARY KEY, user_id INT NOT NULL, total_amount DECIMAL(10,2) NOT NULL, status VARCHAR(20) NOT NULL, created_at DATETIME NOT NULL, cancel_reason VARCHAR(255) ); 要求 1. user_id必须从1到50之间取值保证外键有效 2. status覆盖pending\paid\shipped\completed\cancelled 3. created_at从2024-01-01开始按随机递增顺序排列 4. cancelled状态的记录cancel_reason不为NULL其他状态为NULL 5. 只输出INSERT语句每行一条这里最核心的改动是第1条在提示词里告诉它父表的已有数据范围。ChatGPT本身不知道你的外键约束它只会从字段语义上推断user_id应该是个整数但具体数值落在哪个区间完全靠你喂给它。你不是在跟它商量是在给它定规格。另外有个经验SQL脚本生成后别直接跑先grep -c INSERT INTO数一下条数对不对。我遇到过几次它明明承诺生成60条实际输出只有58条或是有几条因为格式问题被截断的情况。这种低级错误人工检查一分钟就能发现但漏过去的话后面接口联调排查半天才发现是数据少了冤枉路走得太多。3.3 性能测试的CSV大文件压测场景造数需求量动辄几万、几十万条。ChatGPT虽然不能一口气生成10万行输出长度有上限但它有一个非常聪明的用法生成一个高覆盖率的种子样本再用脚本去扩展。我的做法是这样的先让ChatGPT生成100条结构正确、场景覆盖全面的CSV数据字段包括用户ID、商品ID、下单时间、金额等。然后用一段简单的Python脚本把100条循环复制、并随机做微量变换扩展到几万行。import csv import random with open(seed.csv) as f: reader csv.reader(f) rows list(reader) # 表头单独处理 header rows[0] data rows[1:] base_time 1704067200 # 2024-01-01 00:00:00 时间戳 generated [] for i in range(50000): row random.choice(data).copy() # 用户ID和数据ID在范围内随机偏移 row[0] str(random.randint(1, 5000)) row[1] str(random.randint(1, 200)) # 时间戳递推模拟分布 row[3] str(base_time random.randint(0, 180 * 86400)) generated.append(row) with open(large_test.csv, w, newline) as f: writer csv.writer(f) writer.writerow(header) writer.writerows(generated)这个思路的核心是ChatGPT负责质脚本负责量。Excellent seed data scale-up script, 比让AI硬编10万条数据靠谱得多也快得多。实测造5万条CSV文件整个过程不到一分钟而如果手写脚本造数据光字段规则就得写小半天。4. 生成结果别直接用先过这三道筛子4.1 幻觉才是最大风险说句公道话ChatGPT生成测试数据最大的问题不是效率而是它会在细节上骗你。这些错误藏得很深看起来一切正常其实经不起推敲。我遇到过的翻车案例包括生成手机号时用了18800001111这种一看就是造出来的号或者干脆出现11位全相同的假号生成邮箱时域名五花八门部分格式直接非法比如testqq.com生成日期时出现2023-02-31这种不存在的日期生成SQL时字段名跟建表语句不一致少个下划线你都不容易发现说是100条数据实际数下来只有96条中间有重复这背后的原因很简单ChatGPT本质是一个语言模型它的目标是生成看起来合理的文本而不是真实验证过正确的数据。你写email字段要合法它知道邮箱大概长什么样但它并不会逐条用正则去校验。所以我的建议是任何ChatGPT生成的测试数据在进入环境之前必须过一层自动校验。别偷懒别想着AI生成的应该没问题这六个字是事故的开端。4.2 边界值没覆盖让ChatGPT自己当测试员有一个技巧我觉得特别实用生成完数据后追加一条对话让ChatGPT自我检查。请检查你上面生成的数据逐条核对以下规则 1. 金额字段是否为两位小数且不存在负数 2. 时间字段是否都在2024-01-01之后 3. 状态为cancelled的记录是否都有取消原因 4. 是否有重复的主键 5. 邮箱字段是否符合格式规范 如果发现问题请列出具体的行号和问题描述不要自行修改数据。注意最后那句不要自行修改数据很关键。因为如果你不说它可能给你重新生成一版说已修复但你又不知道它改了哪些地方等于数据不可追溯了。让它只报告问题你来决定怎么改这是把AI当检查工具而不是决策者的正确姿势。不过我也要说实话这个自查能力只能过滤掉一部分问题。像日期2023-02-31这种它不一定能发现所以还得靠代码。4.3 一套最小验证脚本的写法针对生成的数据我建议写一个最简验证脚本不用做成框架够用就行。核心逻辑就是读取数据文件逐条验证关键规则有错就打印行号和问题。用CSV数据当例子import csv import re from datetime import datetime email_pattern re.compile(r^[\w\.-][\w\.-]\.\w$) valid_status {pending, paid, shipped, completed, cancelled} with open(orders.csv) as f: reader csv.DictReader(f) for i, row in enumerate(reader, start2): # 从第2行开始跳过表头 errors [] try: amount float(row[total_amount]) if amount 0: errors.append(金额为负数) except ValueError: errors.append(金额不是合法数字) if row[status] not in valid_status: errors.append(f非法状态值: {row[status]}) if row[status] cancelled and not row[cancel_reason]: errors.append(cancelled状态缺少取消原因) if not email_pattern.match(row[email]) if email in row else False: errors.append(邮箱格式非法) try: datetime.strptime(row[created_at], %Y-%m-%d %H:%M:%S) except ValueError: errors.append(f日期格式非法: {row[created_at]}) if errors: print(f第{i}行: {row.get(order_id, N/A)} - {, .join(errors)}) print(校验完成)这个脚本看起来简单但它能拦住我文章里提到的大部分真实翻车场景。把这段代码保存成validate_test_data.py每次ChatGPT生成完数据跑一遍有问题改提示词重新生成形成了正向循环。我从开始用这个流程之后测试数据返工率明显下降。5. 从一次性生成到可持续的数据流水线5.1 把提示词沉淀成团队模板用了一段时间之后我发现一个问题每次都要从零写提示词效率还是不够高。比如订单模块做完了下个项目是支付模块表结构变了但提示词的骨架其实是类似的——都要约束枚举值、关联字段、时间分布、输出格式。于是我把提示词做成了团队模板存在项目的testdata/prompts/目录下。每个模板包含表结构说明、字段约束、场景列表、输出格式要求四个部分。新项目来的时候先改表结构再微调字段约束10分钟就能出一套可复用的数据生成方案。模板长这样# 项目[模块名] / 表[表名] ## 表结构 [粘贴建表语句] ## 字段约束 - [字段A]枚举值只能取[x/y/z] - [字段B]与[字段C]存在依赖关系说明具体逻辑 - [字段D]格式约束说明具体要求 ## 场景覆盖 - 场景1[描述] - 场景2[描述] ## 输出要求 - 格式[JSON/SQL/CSV/Markdown] - 条数[具体数量] - 附加只输出数据不要解释5.2 结合脚本实现批量迭代模板化之后我又往前走了一步把ChatGPT的使用和脚本流程串起来。现在我的工作流是从模板库复制合适的数据生成提示词按当前项目的表结构微调字段信息丢给ChatGPT生成种子数据跑验证脚本检查规则有问题回到第3步微调提示词重新生成通过验证后用扩展脚本生成大批量数据把最终文件按固定命名规则放进testdata/目录供测试脚本引用这套流程跑顺之后一个中等复杂度的模块从提需求到拿到经过验证的测试数据基本能控制在半小时以内。以前同样的事情我需要半天到一天。还试过用ChatGPT API把这套流程自动化思路是用Python调用接口把模板提示词发过去接收结果自动存成文件再自动跑验证脚本。这样连复制粘贴那步都省了。不过说实话日常使用中Web版交互式调整提示词更灵活API方案适合需要长期重复执行的固定场景。5.3 遇到的坑和我的备选方案最后聊几个实操中的坑都是我自己踩过的。第一个坑ChatGPT偶尔会忘事。尤其是在长对话里让它在之前基础上追加数据它可能生成的和前面风格完全不搭甚至字段都对不上。我的解决办法是每次生成数据都用新对话把完整的表结构和约束重新贴一遍不依赖上下文记忆。虽然多花点token但换来的是规范性。第二个坑同一个提示词每次生成的结果都不一样。这既是优点也是缺点。优点是能给测试带来随机性缺点是你没法保证这次的结果跟上次一样。如果你的测试用例对数据有固定依赖比如某个特殊ID那就把生成结果先存到固定的测试数据文件里不要每次跑测试都重新生成。第三个坑数据量一次别贪多。我在前面提过让ChatGPT一次生成100条效果最好一次让它生成1000条经常出现中途截断、数据缺失的问题。量大的话分批生成再合并或者走种子样本加脚本扩展的路线。第四个坑别让它生成真实感太强的数据。比如身份证号、真实手机号这类敏感信息一方面有合规风险另一方面容易让测试数据混入真实数据。我都在提示词里明确加上一句所有字段使用测试专用的虚构数据手机号使用192开头等测试号段。这样既满足格式要求又不会越界。从个人的体验来说ChatGPT生成测试数据这件事本质上是把一个从规则到实例的转换过程自动化了。它未必能替代那些复杂到需要精确控制每一位字符的数据场景但绝对能覆盖日常测试中80%以上的造数需求。我现在的工作习惯是先让ChatGPT出一版数据再把自己的测试设计经验叠加进去用验证脚本兜底。这种AI出初稿、人来定标准的配合方式比我之前任何一代造数方案都顺手得多。如果你也经常被造数据这件事折磨建议直接从最简单的场景开始试挑一张你手头最常测的表把表结构和约束丢给ChatGPT生成20条试试水。跑完这一轮你大概就能理解为什么我标题里说高效到怀疑人生了。