如果你手里有一笔马上就要过期的 LLM(大语言模型)API 额度,你会拿它干什么?
看着后台倒计时的日期,很多人的第一反应是:必须赶紧薅完这最后一把羊毛! 可是手动在网页端对话实在太慢了。作为一个程序员,我的思路很明确:找一个极其消耗 Token、平时懒得做、但做了又极具价值的“重体力活”,写个自动化脚本让大模型在后台满负荷跑起来。
经过一番衡量,我放弃了“让 AI 重构老代码”(因为幻觉风险太高,且侵入性强),最终锁定了一个完美的满级耗流任务:全项目自动化补全单元测试。
今天,就手把手教你如何用几十行 Python 脚本,结合 DeepSeek V3.2 的强大代码能力,安全、高效地把你的 Node.js 项目单测覆盖率强行拉满!
💡 为什么选“生成单元测试”?
在压榨 API 剩余价值时,生成单测有三大无可比拟的优势:
- 绝对安全,零生产风险: 它是非侵入式的。AI 只会生成独立的测试文件,就算它胡言乱语写错了,大不了就是测试跑不过,绝对不会把你原本跑得好好的业务逻辑搞崩。
- 真正的“耗 Token 巨兽”: 单元测试的代码量往往比业务代码还要大。为了覆盖各种边界条件、Mock 外部接口,AI 需要疯狂输出,烧额度效率极高。
- 消除技术债的利器: 平时业务迭代紧,单测总是被搁置。趁这个机会把历史包袱甩给 AI,以后重构代码底气都足了。
🛠️ 核心思路与武器库
为了让大模型吐出的测试代码高质量且不破坏现有目录,我们采用了以下策略:
- 目标精准制导: 只扫描核心业务目录(如
controllers,services,models,utils等),跳过静态资源和文档。 - 安全隔离: 所有生成的测试文件统一存放在一个全新的
ai_generated_tests文件夹中。 - 高并发请求: 使用 Python 的
asyncio和aiohttp替代单线程请求,最大化并发吞吐量。
你需要准备的武器:
- 一个 Node.js 后端项目(本文以 Express/Koa + Jest 为例)。
- Python 3.8+ 环境(用于运行高并发请求脚本)。
- 即将过期的 API Key(本文以硅基流动平台调用的 DeepSeek-V3 为例)。
🚀 实战代码:Python 高并发生成脚本
在你的 Node.js 项目根目录下,新建一个 burn_api.py 文件,贴入以下代码。
(⚠️ 注意:运行前请先在终端执行 pip install openai asyncio 安装依赖)
import os
import asyncio
from openai import AsyncOpenAI
# ================= 配置区 =================
# 🚨 警告:切勿将真实的 API Key 提交到公开仓库!
API_KEY = "sk-你的真实API_KEY"
BASE_URL = "https://api.siliconflow.cn/v1" # 这里以硅基流动为例
MODEL = "deepseek-ai/DeepSeek-V3"
# 精准制导:只扫描包含核心逻辑的文件夹
TARGET_DIRS = ["controllers", "services", "models", "middlewares", "utils"]
# 安全隔离:生成的代码存放在全新文件夹
TEST_DIR = "./ai_generated_tests"
FILE_EXTENSIONS = ('.js', '.ts')
TEST_SUFFIX = ".test"
# 并发数控制:如果遇到 429 报错,请适当调低
CONCURRENCY_LIMIT = 5
# ==========================================
client = AsyncOpenAI(api_key=API_KEY, base_url=BASE_URL)
SYSTEM_PROMPT = """你是一个资深的 Node.js 测试开发工程师。请为以下代码编写严密的单元测试。
要求:
1. 使用 Jest 测试框架。
2. 覆盖正常逻辑(Happy Path)与异常边界条件(Edge Cases)。
3. 涉及数据库、外部网络请求或文件系统时,必须使用 jest.mock() 进行深度 Mock,绝不能发起真实请求。
4. 使用 describe 块组织测试套件,用 it() 提供清晰的中文测试用例说明。
严格限制:你必须且只能输出纯测试代码本身!不要包含任何解释、问候语或 Markdown 代码块标记(如 ```javascript)。"""
async def generate_tests(file_path, content, semaphore):
async with semaphore:
print(f"🧪 正在请求 API 生成单测: {file_path}...")
try:
response = await client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": content}
],
temperature=0.1, # 低温度保证测试逻辑严谨不发散
max_tokens=4000
)
return response.choices[0].message.content
except Exception as e:
print(f"❌ 处理 {file_path} 失败: {e}")
return None
async def process_file(base_dir, file_name, semaphore):
file_path = os.path.join(base_dir, file_name)
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
if not content.strip():
return
test_content = await generate_tests(file_path, content, semaphore)
if test_content:
# 清理可能残留的 Markdown 标记
if test_content.startswith("```"):
test_content = "\n".join(test_content.split("\n")[1:])
if test_content.endswith("```"):
test_content = "\n".join(test_content.split("\n")[:-1])
# 还原目录结构,例如:ai_generated_tests/controllers/user.test.js
name, ext = os.path.splitext(file_name)
test_file_name = f"{name}{TEST_SUFFIX}{ext}"
out_dir = os.path.join(TEST_DIR, base_dir)
os.makedirs(out_dir, exist_ok=True)
out_file_path = os.path.join(out_dir, test_file_name)
with open(out_file_path, 'w', encoding='utf-8') as f:
f.write(test_content)
print(f"✅ 成功保存: {out_file_path}")
async def main():
if not os.path.exists(TEST_DIR):
os.makedirs(TEST_DIR)
semaphore = asyncio.Semaphore(CONCURRENCY_LIMIT)
tasks = []
for target in TARGET_DIRS:
if not os.path.exists(target):
continue
for root, _, files in os.walk(target):
for file in files:
if file.endswith(FILE_EXTENSIONS) and TEST_SUFFIX not in file:
tasks.append(process_file(root, file, semaphore))
if not tasks:
print("未找到需要处理的代码文件。")
return
print(f"🚀 共找到 {len(tasks)} 个文件,开始高并发生成...")
await asyncio.gather(*tasks)
print("\n🎉 全部单元测试生成完毕!API 额度燃烧成功!")
if __name__ == "__main__":
asyncio.run(main())
配置好你的 API_KEY 后,只需在终端运行 python burn_api.py,你就可以端起咖啡,看着终端里不断弹出的“✅ 成功保存”,享受自动化带来的赛博快感了。
📦 运行测试:如何验收 AI 的工作成果?
代码生成完毕后,你的项目根目录会多出一个 ai_generated_tests 文件夹。接下来我们要把它跑起来。
1. 安装 Jest(如果还没装的话)
npm install --save-dev jest supertest
**2. 配置 package.json**
在 scripts 中添加一条专门运行 AI 测例的命令:
"scripts": {
"test:ai": "jest ./ai_generated_tests --coverage"
}
3. 一键验收
npm run test:ai
🚧 避坑指南:AI 代码的“通病”与修复
当你按下回车,大概率会看到满屏的红色报错。别慌!这不是模型傻,而是大模型在没有整个文件系统上下文时,必然会遇到的“相对路径瞎猜”问题。
只要掌握以下三招,一小时内就能让测试满眼飘绿:
- 修复
require路径报错:
大模型经常搞错引入层级(比如报Cannot find module '../../controllers/user')。你需要手动打开报错的测试文件,把顶部的相对路径修正(比如多加一层../)。 - 处理数据库连通性问题:
即便你在 Prompt 里要求了 Mock,它有时还是会试图连接真实数据库。报错时,只需在测试文件顶部手动补上一句jest.mock('../../models/user')即可。 - 修复
app is not defined:
在测试 Controller 时,AI 喜欢用supertest(app),但它不知道你的app.js具体在哪。检查测试文件顶部,确保正确引入了你的 Express/Koa 实例:const app = require('../../app');。
🛡️ 最后的安全叮嘱
无论在何种情况下,都不要把含有真实 API Key 的脚本提交到 Git 仓库! 额度跑完后,立刻去控制台把当前的 Key 删除作废,养成良好的安全习惯。
版权属于:soarli
本文链接:https://blog.soarli.top/archives/919.html
转载时须注明出处及本声明。