本文主要对往期实现的llm模块与logger模块进行单元测试代码的编写与运行,以及如何创建一个新的测试用例同时简单设计一下单元测试目录结构,统一往后的单元测试模块开发标准
test/├── readme.md # 单元测试说明文档├── ajax-test/ # AJAX 接口测试用例│ ├── request.util.js # AJAX 请求公用工具│ ├── example.test.js # 示例模块测试│ └── llm.test.js # LLM 模块测试└── logger-test/ # 日志模块测试用例├── logger.util.js # 日志测试公用工具├── logger.test.js # 日志写入测试└── logger.clear.js # 日志清理测试
[测试模块名].test[测试子模块名].test.js[主体作用范围].util.js// 等待异步操作完成await new Promise((resolve) => setTimeout(resolve, 500));// 并发请求const promises = [];for (let i = 0; i < 10; i++) {promises.push(request(server, "GET", `/api/test?_t=${i}`));}await Promise.all(promises);
使用node命令对测试文件进行启动,往期文章提到过node命令运行js文件,如需查看可参考NodeJS+Koa学习笔记(0-2)Node.js 项目初始化
node --test test/logger-test/logger.test.jsnode --test test/logger-test/logger.clear.jsnode --test test/logger-test/*.test.jsnode --test --test-reporter=spec test/ajax-test/example.test.jsnode --test --test-name-pattern="创建日志目录结构与日志文件" test/ajax-test/example.test.js/*** test/logger.test.js* 日志模块单元测试* 验证:日志目录初始化*/import { describe, it, before, after } from "node:test";import assert from "node:assert/strict";import fs from "node:fs";import path from "node:path";import { fileURLToPath } from "node:url";import Koa from "koa";import Logger from "../../src/middlewares/logger.js";import { terminateWorker } from "../../plugin/lee-logger/main.js";import { sendRequest } from "./logger.util.js";const __filename = fileURLToPath(import.meta.url);const __dirname = path.dirname(__filename);const ROOT_DIR = path.resolve(__dirname, "../");/*** 创建带 Logger 中间件的最小测试用 Koa 应用* 仅注册 Logger 中间件和一个简单的响应路由,不依赖数据库* @returns {Koa}*/function createLoggerTestApp() {const app = new Koa();// 注册日志中间件app.use(async (ctx, next) => Logger(ctx, next));// 简单响应路由app.use(async (ctx) => {ctx.status = 200;ctx.body = { code: 200, msg: "ok" };});return app;}/*** 获取当前日期对应的日志文件路径* 目录结构:log/YYYY-MM/YYYY-MM-DD(01).txt*/function getExpectedLogFilePath() {const now = new Date();const yyyy = String(now.getFullYear());const mm = String(now.getMonth() + 1).padStart(2, "0");const dd = String(now.getDate()).padStart(2, "0");const monthDir = `${yyyy}-${mm}`;const dayFile = `${yyyy}-${mm}-${dd}(01).txt`;return path.join(ROOT_DIR, "log", monthDir, dayFile);}describe("日志模块测试", () => {let server;const logFilePath = getExpectedLogFilePath();before(async () => {server = createLoggerTestApp().listen(0);});after(async () => {server?.close();// 终止 Worker 线程,使进程可正常退出await terminateWorker();});it("创建日志目录结构与日志文件", async () => {// 发起请求以触发 Logger 中间件await sendRequest(server, "GET", "/test-logger?pageNum=1&pageSize=10");// 等待 Worker 线程完成写入(异步,给 500ms 缓冲)await new Promise((resolve) => setTimeout(resolve, 500));// 验证日志目录是否存在const logDir = path.dirname(logFilePath);assert.ok(fs.existsSync(logDir), `日志月份目录应存在: ${logDir}`);// 验证日志文件是否存在assert.ok(fs.existsSync(logFilePath), `日志文件应存在: ${logFilePath}`);});});
app.listen(0) 使用随机端口测试测试用例https://node.org.cn/docs/latest/api/test.html
断言测试https://node.org.cn/docs/latest/api/assert.html
本文核心点在于如何设计一个单元测试模块的开发标准,主要在于目录结构与命名规范,技术点主要在于多请求并发实现方式与测试文件的单个、多个的运行方式。