如何在tap测试通过后自动生成openapi.yml文件?
如何在Tap测试完成后自动生成OpenAPI YAML文件?
需求与当前配置
需要在所有Tap测试完成后自动生成openapi.yml,已在.taprc中配置after钩子:
after: utils/generateOpenApi.ts
生成脚本utils/generateOpenApi.ts
const helper = require('fastify-cli/helper.js') import fs from 'fs' import path from 'path' const generateOpenApi = async() => { const argv = [path.join(__dirname, '..', 'src', 'app.ts')] const app = await helper.build(argv, {}) console.log('app.swagger', app.swagger) const yaml = app.swagger({ yaml: true }); fs.writeFileSync("swagger.yaml", yaml); } generateOpenApi()
主应用文件src/app.ts(含语法错误)
import { FastifyPluginAsync } from "fastify"; import { buildJsonSchemas, register } from "fastify-zod"; import { join } from "path"; import AutoLoad, { AutoloadPluginOptions } from "@fastify/autoload"; import { type FastifyZod } from "fastify-zod"; import { models } from "./routes/users/users.schemas"; export type AppOptions = { // 自定义应用配置 } & Partial<AutoloadPluginOptions>; const options: AppOptions = {}; declare module "fastify" { interface FastifyInstance { readonly zod: FastifyZod<typeof models>; } } const app: FastifyPluginAsync<AppOptions> = async ( fastify, opts ): Promise<void> => { await register(fastify, { jsonSchemas: buildJsonSchemas(models, { errorMessages: true }), swaggerOptions: { swagger: { info: { title: "Fastify API", description: "基于Node.js、MongoDB、Fastify和Swagger构建的高性能REST API", version: "0.1.0", }, host: "localhost", schemes: ["http"], consumes: ["application/json"], }, }, swaggerUiOptions: { routePrefix: "/docs", uiConfig: { docExpansion: "full", deepLinking: false, }, uiHooks: { onRequest: function (request, reply, next) { next(); }, preHandler: function (request, reply, next) { next(); }, }, staticCSP: true, transformStaticCSP: (header) => header, transformSpecification: (swaggerObject, request, reply) => { return swaggerObject; }, transformSpecificationClone: true, }, }); void fastify.register(AutoLoad, { dir: join(__dirname, "plugins"), options: opts, }); void fastify.register(AutoLoad, { dir: join(__dirname, "routes"), options: opts, ignorePattern: /.*(schemas)\.ts/ }); }; export default app; export { app, options }; // 原代码此处缺失"s"和闭合括号,已修正
问题排查与修复方案
1. Tap钩子执行环境问题
Tap默认用Node.js执行脚本,但generateOpenApi.ts是TypeScript文件,Node无法直接运行:
- 修改
.taprc,指定用ts-node执行:after: ts-node utils/generateOpenApi.ts - 安装依赖:
npm install -D ts-node typescript
2. Fastify Swagger注册错误
fastify-zod的register调用方式有误,需挂载到Fastify实例上:
// 修正app.ts中的注册逻辑 await fastify.register(register, { jsonSchemas: buildJsonSchemas(models, { errorMessages: true }), swaggerOptions: { /* 原有配置 */ }, swaggerUiOptions: { /* 原有配置 */ } });
同时确保安装Swagger依赖:
npm install @fastify/swagger @fastify/swagger-ui
3. 脚本模块兼容与输出修正
- 统一使用ES模块,替换混合的CommonJS导入:
import helper from 'fastify-cli/helper.js'; import fs from 'fs/promises'; import path from 'path'; const generateOpenApi = async() => { const argv = [path.join(__dirname, '..', 'src', 'app.ts')]; const app = await helper.build(argv, {}); if (!app.swagger) { throw new Error('Fastify应用未注册Swagger插件'); } const yaml = app.swagger({ yaml: true }); // 生成需求的openapi.yml文件 await fs.writeFile(path.join(process.cwd(), 'openapi.yml'), yaml); console.log('OpenAPI规范已成功生成到openapi.yml'); }; // 捕获错误并退出,确保Tap能感知失败 generateOpenApi().catch(err => { console.error('生成OpenAPI规范失败:', err); process.exit(1); });
4. 验证钩子执行
运行测试时添加--verbose参数,确认after脚本是否执行:
npx tap --verbose
若脚本未执行,检查.taprc是否在项目根目录,或手动指定配置文件:
npx tap --config .taprc
内容的提问来源于stack exchange,提问作者Bart Krakowski
相关产品推荐
相关产品推荐

