news 2026/10/12 3:07:36

Codex入门07-自动测试(小白入门:让AI帮你写测试用例,再也不用自己苦哈哈写)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Codex入门07-自动测试(小白入门:让AI帮你写测试用例,再也不用自己苦哈哈写)

1. 为什么你的项目需要 Codex 自动测试

很多人第一次听到「自动测试」四个字,脑子里浮现的是加班到深夜、一行行手写expect的画面。我一开始也这么想,直到被一个真实事故教育了:改了一个价格计算函数的参数顺序,本地跑页面看着没问题,上线后购物车金额全错,客服电话被打爆。那次之后我才明白,测试不是给领导看的 KPI,而是你代码的「安全网」——它在你改动代码的瞬间告诉你哪里塌了。

Codex 自动测试要解决的问题很具体:让 AI 帮你写测试用例,你只负责审查和运行。它适合三类人:刚学前端、还没养成写测试习惯的新手;维护老项目、想补测试但不知道从哪下手的开发者;以及用 Vue3 + Vite 做业务、天天改工具函数却不敢重构的人。核心检索词就三个:Codex、自动测试、Vitest 测试用例。

传统写测试的流程是:读源码 → 想边界条件 → 写 describe/it → 跑 → 报错 → 改。Codex 把这个流程压缩成一句话提示词,它读完你的源文件后直接产出可运行的测试文件。但注意,AI 生成的测试不是免检产品,它可能漏掉空值、可能把断言写反、可能 mock 得不对。所以本文交付的不是「一键生成就完事」,而是完整的生成 → 运行 → 修正闭环,让你跑通第一个自动测试流程后,能自己判断 AI 写的测试靠不靠谱。

下面我会用一个价格工具函数src/utils/price.ts作为被测试对象,从零配置 Vitest 环境开始,到让 Codex 生成单元测试,再到运行失败后让 AI 分析原因并修复。全程命令可复制,配置片段可直接落盘。你跟着做一遍,就能把这套方法迁移到自己项目的任意模块上。

2. TaoToken 前置准备:拿到 Key 并接入 Codex

Codex 本身是命令行里的编码助手,它要调用大模型才能生成测试代码,所以你需要一个稳定的模型接入点。这里用 TaoToken 来做前置配置,它提供 OpenAI 兼容的接口,Codex 可以直接对接。整个准备分三步:注册拿 Key、配置 Codex 的认证文件、验证连通性。

先说拿 Key。打开官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,注册后在控制台里创建一个 API Key。控制台地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,进去后左侧菜单找「API Keys」,点新建,复制那串sk-开头的字符串。这个 Key 只显示一次,丢了就得重建,所以先粘到安全的地方。

接下来配置 Codex。Codex 读取的是~/.codex/auth.json这个文件(Windows 下是C:\Users\你的用户名\.codex\auth.json)。如果目录不存在就手动建一个。文件内容长这样:

{ "OPENAI_API_KEY": "sk-你从TaoToken复制的Key", "OPENAI_BASE_URL": "https://taotoken.net/api" }

注意OPENAI_BASE_URL后面不要加/v1,Codex 会自己拼路径。这一点很多人踩坑,加了/v1会变成/v1/v1/chat/completions,直接 404。保存后,在终端里跑一句验证:

codex --version

能打印版本号说明 Codex 装好了。再跑一个最小请求确认 Key 有效:

curl https://taotoken.net/api/v1/models \ -H "Authorization: Bearer sk-你的Key"

返回一个 JSON 列表,里面有模型 ID,就说明 Key 和网络都通了。如果返回 401,说明 Key 复制错了或者多了空格;如果返回连接超时,检查一下是不是公司网络限制了外部请求。

模型 ID 这块,Codex 默认会用配置里的模型,你也可以在提示词里显式指定。常用的编码模型 ID 可以在接入文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 里查到。如果你打算长期用 Codex 做编码和 Agent 任务,可以考虑 Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite ,它按周期计费,比按量付费更适合高频写测试的场景。

三件套记牢:Base URL 是https://taotoken.net/api,Key 是sk-开头那串,Model ID 从文档里选一个编码能力强的。这三个填对,Codex 才能正常工作。配置完别急着写测试,先在项目根目录跑一次codex进交互模式,随便问一句「你好」,能回话就说明链路通了。

3. 可复制配置:Vitest 环境初始化与 Codex 提示词模板

环境配置是新手最容易卡住的地方。我见过太多人测试文件写好了,跑npm run test报「command not found」,或者报「document is not defined」,本质都是 Vitest 没配对。这一节给你两样东西:一份可直接落盘的 Vitest 配置,一套可复用的 Codex 提示词模板。

先装依赖。假设你是 Vue3 + Vite 项目,在根目录执行:

npm install -D vitest @vue/test-utils jsdom @vitejs/plugin-vue

四个包各司其职:vitest是测试运行器,@vue/test-utils提供mount挂载组件,jsdom模拟浏览器 DOM 环境,@vitejs/plugin-vue让 Vitest 能解析.vue单文件组件。装完在package.json的scripts里加一行:

{ "scripts": { "test": "vitest run", "test:watch": "vitest" } }

vitest run跑一次就退出,适合 CI;vitest是监听模式,改文件自动重跑,本地开发用这个。

然后是配置文件vitest.config.ts,放在项目根目录:

import { defineConfig } from 'vitest/config' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], test: { environment: 'jsdom', globals: true, include: ['src/**/*.{test,spec}.{ts,js}'], coverage: { provider: 'v8', reporter: ['text', 'html'] } } })

逐行解释关键项:environment: 'jsdom'让测试里能用document、window,测组件必须开;globals: true让你不用每个文件都import { describe, it, expect },省事;include限定测试文件范围,避免它去扫node_modules;coverage是覆盖率配置,provider: 'v8'比默认的 istanbul 快,reporter里text在终端看,html生成网页报告。

配置完先跑一次空测试确认环境没问题:

npm run test

如果提示「No test files found」,说明配置生效了,只是还没写测试。如果报Cannot find module 'jsdom',回去检查依赖装没装。

现在到 Codex 提示词模板。我实测下来,提示词写得越结构化,生成的测试质量越高。模板如下:

帮我给 src/utils/price.ts 写完整的单元测试,使用 Vitest。 要求覆盖以下场景: 1. 正常输入(整数、小数) 2. 边界值(0、最大值、折扣为 0 和 1) 3. 异常输入(负数、超出范围的折扣) 4. 精度问题(小数乘法后的舍入) 测试文件放在 src/utils/__tests__/price.test.ts。 每个 it 的描述用中文,断言要具体,不要用 toBeTruthy 这种模糊断言。

这个模板的四个要点:指定文件路径让 Codex 知道读哪个源文件、列出场景避免它只写 happy path、指定输出路径方便你直接落盘、约束断言风格防止它写expect(result).toBeDefined()这种没意义的测试。把这套模板存成代码片段,以后换文件只改路径和场景列表就行。

4. 验证请求:生成-运行-修正完整闭环

配置就绪,现在跑一次完整流程。被测试的源文件src/utils/price.ts内容如下:

export function calculateDiscount(price: number, discount: number): number { if (price < 0) throw new Error('价格不能为负数') if (discount < 0 || discount > 1) throw new Error('折扣必须在0-1之间') return Math.round(price * discount * 100) / 100 } export function formatPrice(price: number): string { return `¥${price.toFixed(2)}` }

在项目根目录启动 Codex,把上一节的提示词模板粘进去。它会读文件、分析逻辑、生成测试。生成的src/utils/__tests__/price.test.ts大致如下:

import { describe, it, expect } from 'vitest' import { calculateDiscount, formatPrice } from '../price' describe('calculateDiscount', () => { it('应正确计算折扣价', () => { expect(calculateDiscount(100, 0.8)).toBe(80) expect(calculateDiscount(200, 0.5)).toBe(100) }) it('应正确处理小数精度', () => { expect(calculateDiscount(99.9, 0.7)).toBe(69.93) }) it('价格为0时返回0', () => { expect(calculateDiscount(0, 0.8)).toBe(0) }) it('折扣为1时返回原价', () => { expect(calculateDiscount(100, 1)).toBe(100) }) it('价格为负数时抛出错误', () => { expect(() => calculateDiscount(-1, 0.8)).toThrow('价格不能为负数') }) it('折扣超出范围时抛出错误', () => { expect(() => calculateDiscount(100, 1.5)).toThrow('折扣必须在0-1之间') }) }) describe('formatPrice', () => { it('应正确格式化整数价格', () => { expect(formatPrice(100)).toBe('¥100.00') }) it('应正确格式化小数价格', () => { expect(formatPrice(99.9)).toBe('¥99.90') }) })

现在运行:

npm run test

预期输出类似:

✓ src/utils/__tests__/price.test.ts (8 tests) 12ms Test Files 1 passed (1) Tests 8 passed (8)

8 个测试全绿,说明 AI 生成的测试和源码逻辑一致。但别急着庆祝,真正的价值在失败场景。我故意把源码里的Math.round(price * discount * 100) / 100改成price * discount,再跑一次:

FAIL src/utils/__tests__/price.test.ts > calculateDiscount > 应正确处理小数精度 AssertionError: expected 69.93000000000001 to be 69.93

测试精准抓到了浮点精度问题。这时候把报错信息连同源码一起丢给 Codex:

运行 npm run test 后,calculateDiscount 的小数精度测试失败, 报错 expected 69.93000000000001 to be 69.93。 请分析原因并修复源码(优先改源码,不要改测试断言)。

Codex 会指出浮点乘法精度丢失,建议恢复Math.round舍入逻辑。改完再跑,全绿。这个「生成 → 运行 → 失败 → 修正」的循环,就是你以后每次改代码都要走的流程。测试不是写完就扔,它是活的,跟着源码一起演进。

5. 常见报错排查:401、local proxy failed 与 reading choices

跑 Codex 自动测试的过程中,报错基本集中在两类:模型接入报错和测试运行报错。我把踩过的坑按报错原文列出来,你对照着查。

401 Unauthorized。这是最常见的接入错误,终端里长这样:

Error: 401 Unauthorized - {"error":{"message":"Invalid API key"}}

三个原因:Key 复制时带了空格或换行、Key 已过期被删、auth.json里字段名写错。排查方法:重新从控制台复制 Key,用cat ~/.codex/auth.json检查文件内容,确认OPENAI_API_KEY的值前后没有多余字符。如果 Key 没问题,检查OPENAI_BASE_URL是不是写成了https://taotoken.net/api/(末尾多了斜杠),去掉斜杠再试。

local proxy failed。报错原文:

Error: local proxy failed: connect ECONNREFUSED 127.0.0.1:7890

这说明你的终端环境变量里配了本地代理,但代理服务没启动。检查HTTP_PROXY和HTTPS_PROXY两个环境变量:

echo $HTTP_PROXY echo $HTTPS_PROXY

如果有值且你不需要代理,直接unset HTTP_PROXY HTTPS_PROXY清掉,再跑 Codex。注意,TaoToken 的接口是直连的,不需要任何代理配置,环境里残留的代理设置反而会干扰。

reading choices 报错。这个通常出现在模型返回格式异常时:

TypeError: Cannot read properties of undefined (reading 'choices')

原因是接口返回的 JSON 结构里没有choices字段,多半是 Base URL 拼错了导致请求打到了错误端点。确认OPENAI_BASE_URL是https://taotoken.net/api,不带/v1。如果还报,用 curl 手动打一次接口看返回结构:

curl https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer sk-你的Key" \ -H "Content-Type: application/json" \ -d '{"model":"你的模型ID","messages":[{"role":"user","content":"hi"}]}'

返回里有choices数组就说明接口正常,问题在 Codex 配置;返回错误信息就按错误提示处理。

OAuth 相关报错。如果你之前用过其他需要 OAuth 登录的工具,auth.json里可能残留了tokens字段,和OPENAI_API_KEY冲突。最干净的做法是删掉整个auth.json重建,只保留OPENAI_API_KEY和OPENAI_BASE_URL两个字段。

测试侧报错。ReferenceError: document is not defined说明vitest.config.ts里environment没设成jsdom。Cannot find module '@vue/test-utils'说明依赖没装全,重跑npm install -D @vue/test-utils。No test files found检查include路径和实际测试文件位置是否匹配。

排查顺序建议:先 curl 验证 Key 和接口,再检查auth.json字段,最后看测试配置。三件套(Base URL + Key + Model ID)任何一件不对都会报错,逐个确认比瞎改快得多。

6. 把自动测试变成习惯:CTA 与下一步

跑通第一个自动测试后,你要做的不是停下来,而是把它变成肌肉记忆。我的做法是:每次改完一个工具函数,立刻让 Codex 补测试;每次修完一个 bug,让 Codex 针对这个 bug 写一条回归测试。回归测试的意思是,把导致 bug 的输入固定下来,以后任何人改这块代码,测试都会拦住他。这样你的测试集就是项目的历史事故档案,越攒越值钱。

具体操作上,把第 3 节的提示词模板存进你的代码片段库,改文件路径就能复用。测试文件统一放__tests__目录,命名跟源文件对应,比如price.ts对应price.test.ts。跑测试用npm run test:watch,改代码自动重跑,反馈延迟控制在秒级。覆盖率报告用npx vitest run --coverage生成,打开coverage/index.html看哪些行没被覆盖,优先补核心逻辑。

如果你还没配好 Codex 的接入,回到第 2 节,去 API Keys 页面 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 拿 Key,配置文档在接入文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 里。想先感受一下模型生成测试的效果,可以去模型对话 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=chat&utm_campaign=rewrite 里贴一段源码试试。长期用 Codex 做编码和 Agent 任务的话,Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 比按量付费划算。

最后说个我自己的习惯:每次 Codex 生成测试后,我会花 30 秒扫一遍断言,重点看三处——边界值有没有覆盖 0 和最大值、异常分支有没有toThrow、断言是不是具体到数值。AI 写得快,但判断测试有没有意义是你的活。测试是代码的安全网,网眼大小得你自己定。下一篇讲用 Codex 生成 README 文档,同样是「生成 → 审查 → 修正」的套路,感兴趣可以接着看。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/12 3:07:32

布拉格微环与二维材料集成:从仿真到流片的硅光实战经验

搞了半年多的片上光子器件&#xff0c;最近终于把布拉格微环二维集成这个方向跑通了。从最开始连周期光栅和环形波导怎么一起算都摸不着头脑&#xff0c;到现在能稳定出器件、能复现测试结果&#xff0c;中间踩过的坑多得我自己都记不清。这篇就当是编号029的工程笔记吧&#x…

作者头像 李华
网站建设 2026/10/12 3:06:49

Windows下MySQL 8.0安装全攻略:MSI与ZIP双方案详解

先说结论&#xff1a;在Windows上装MySQL 8.0这件事&#xff0c;本身不难&#xff0c;但非常容易在细节上翻车。我见过太多人卡在初始化失败、服务启动不起来、密码策略死活过不去这三个坎上&#xff0c;最后把整个安装包删了又重新下&#xff0c;来回折腾一整天。其实只要搞清…

作者头像 李华
网站建设 2026/10/12 3:05:16

open-code-review:一种降低协作门槛的代码审查新范式

1. “open-code-review”不是新工具&#xff0c;而是一种被低估的协作范式“open-code-review”这个词最近在技术社区里频繁冒头&#xff0c;但它既不是某个刚发布的开源项目&#xff0c;也不是某家大厂推出的审查平台。我第一次在某次跨团队协作中听到它&#xff0c;是位前端导…

作者头像 李华
网站建设 2026/10/12 3:04:37

网络应用层之HTTP

现成的应用层协议 实际上, 已经有大佬们定义了一些现成的, 又非常好用的应用层协议, 供我们直接参考使用. HTTP(超文本传输协议)就是其中之一 一. HTTP HTTP协议中文名为超文本传输协议, 既是最经典的应用层协议, 也是应用最广泛的协议. 它表示客⼾端根据⾃⼰的需要向服务器…

作者头像 李华
网站建设 2026/10/12 3:03:37

超声神经图像语义分割项目实践:数据集质量与模型训练关键点解析

简介&#xff1a;面向医学图像语义分割与超声成像研究&#xff0c;这份深度学习数据集围绕臂丛神经&#xff08;Brachial Plexus&#xff09;区域构建&#xff0c;适用于医学影像专业学生、算法工程师及科研人员开展语义分割模型的训练与验证。数据来自超声背景下的神经图像&am…

作者头像 李华
网站建设 2026/10/12 3:00:43

Windows 下 Git 入门全攻略:从安装配置到分支协作的工程实践

1. 为什么 Windows 用户搞 Git 绕不开这几件事很多刚接触代码或文档协作的人都会碰到这个场景&#xff1a;文件改了几版&#xff0c;最后存成了"报告_最终版_v2_改改_真最终版.doc"&#xff0c;或者写代码写到一半想退回昨天的状态&#xff0c;结果只能靠 CtrlZ 一点…

作者头像 李华