# 软件工程实验 **Repository Path**: Nicky-xiang/software-engineering-lab ## Basic Information - **Project Name**: 软件工程实验 - **Description**: 集成测试与开发的软件工程实验 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-13 - **Last Updated**: 2025-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 图书馆包间预约系统集成与测试文档 ## 项目概述 本项目是对图书馆包间预约系统进行全面的集成与测试工作,旨在确保系统的功能完整性、性能稳定性、安全性和用户体验。测试组负责制定测试策略、设计测试用例、执行测试流程、缺陷管理以及编写测试报告,为系统的质量提供全面保障。 ## 测试目标 1. **功能测试**:验证系统各项功能是否符合需求规格 2. **集成测试**:确保系统各模块间协同工作正常 3. **性能测试**:评估系统在不同负载下的响应时间和稳定性 4. **安全测试**:识别系统潜在的安全漏洞和风险 5. **兼容性测试**:确保系统在不同环境下的正常运行 6. **回归测试**:验证修复后的缺陷不会引入新问题 ## 测试策略 ### 测试方法 - **黑盒测试**:基于系统功能规格进行测试,不关注内部实现 - **白盒测试**:针对代码逻辑和算法进行单元测试 - **自动化测试**:使用自动化工具执行重复性测试任务 - **手动测试**:针对用户界面和复杂场景进行测试 ### 测试环境 - **开发环境**:用于单元测试和集成测试 - **测试环境**:用于功能测试和性能测试 - **预生产环境**:用于系统集成测试和用户验收测试 ### 测试覆盖率目标 - **功能覆盖率**:≥ 95% - **代码覆盖率**:≥ 80% - **分支覆盖率**:≥ 75% ## 测试计划 ### 测试阶段划分 1. **测试准备阶段** - 测试需求分析 - 测试计划制定 - 测试环境搭建 - 测试工具配置 2. **测试设计阶段** - 测试用例设计 - 测试数据准备 - 测试脚本开发 3. **测试执行阶段** - 单元测试 - 集成测试 - 功能测试 - 性能测试 - 安全测试 4. **测试评估阶段** - 缺陷分析 - 测试报告编写 - 质量评估 ### 测试资源配置 - **测试人员**:3名测试工程师 - **测试工具**:Jest、Supertest、Artillery、Postman - **测试环境**:独立的测试服务器、数据库和缓存服务 ## 测试用例设计 ### 单元测试 针对系统各模块的核心功能进行独立测试,确保每个函数和方法的正确性。 ### API测试 验证所有REST API接口的功能、参数验证、错误处理和响应格式。 ### 集成测试 测试系统各组件间的交互,重点关注: - 用户认证与授权流程 - 预约创建与审批流程 - 实时通知功能 - 数据一致性维护 ### 性能测试场景 - 并发用户预约测试 - 批量数据导入性能测试 - 长时间运行稳定性测试 ## 缺陷管理流程 1. **缺陷发现**:记录缺陷详细信息 2. **缺陷分类**:按严重程度和优先级分类 3. **缺陷跟踪**:监控缺陷修复进度 4. **缺陷验证**:确认缺陷修复有效性 5. **缺陷关闭**:完成缺陷生命周期 ## 系统说明 ### 被测系统概述 被测试系统是一个基于 Node.js + Express + TypeScript 开发的图书馆包间预约系统,提供用户管理、包间管理、座位预约等功能。系统采用 JWT 进行身份认证,使用 Redis 实现令牌黑名单和离线消息存储,并支持 WebSocket 实时通知功能。 ## 技术架构 ### 核心技术栈 - **后端框架**:Express.js + TypeScript - **数据库**:MySQL + Sequelize ORM - **身份认证**:JWT (JSON Web Token) - **缓存系统**:Redis - **实时通信**:WebSocket - **文件处理**:xlsx(Excel文件处理) - **密码加密**:bcrypt - **中文拼音**:pinyin ### 项目结构 ``` ├── src/ │ ├── config/ # 配置文件 │ │ ├── database.ts # 数据库配置 │ │ └── redis.ts # Redis配置 │ ├── controllers/ # 控制器 │ │ ├── userController.ts # 用户控制器 │ │ ├── roomController.ts # 包间控制器 │ │ └── notificationController.ts # 通知控制器 │ ├── middleware/ # 中间件 │ │ ├── auth.ts # 认证中间件 │ │ ├── logger.ts # 日志中间件 │ │ └── validation.ts # 验证中间件 │ ├── models/ # 数据模型 │ │ ├── user.ts # 用户模型 │ │ ├── room.ts # 包间模型 │ │ ├── seat.ts # 座位模型 │ │ ├── reservation.ts # 预约模型 │ │ └── notification.ts # 通知模型 │ ├── routes/ # 路由定义 │ │ ├── user.ts # 用户路由 │ │ ├── room.ts # 包间路由 │ │ └── notification.ts # 通知路由 │ ├── services/ # 服务 │ │ ├── websocket.ts # WebSocket服务 │ │ └── notificationService.ts # 通知服务 │ └── app.ts # 应用入口 ├── logs/ # 日志文件 ├── public/ # 公共资源 └── package.json # 项目依赖 ``` ## 系统完整性评估与建议 ### 已完成功能 1. 完整的用户认证与授权系统 2. 包间和楼层管理功能 3. 预约系统核心逻辑 4. WebSocket实时通知 5. 管理员后台功能 ### 待完善功能 1. 预约冲突检测需要增强 2. 预约时间规则需要更灵活配置 3. 缺少预约历史统计功能 4. 系统监控和日志分析功能 5. 前端界面需要优化用户体验 ### 改进建议 1. 增加预约规则配置界面 2. 添加系统使用统计报表 3. 优化WebSocket重连机制 4. 增加系统性能监控 5. 完善单元测试覆盖率 ## 功能特性 ### 用户管理 - 用户登录与注销 - 用户信息管理 - 密码修改 - 管理员批量导入用户 ### 包间管理 - 包间创建、修改、删除 - 包间状态管理(可用、维护中) - 座位管理(创建、修改座位状态) - 座位状态实时更新 ### 预约系统 - 用户预约包间座位 - 预约时间冲突检测 - 预约时间限制(8:00-22:00) - 预约日期限制(当天和后两天) - 周四下午闭馆时间限制 - 管理员审批预约 - 预约状态管理(待审批、已批准、已拒绝、已取消) ### 实时通知 - 基于WebSocket的实时通知系统 - 预约请求通知管理员 - 审批结果通知用户 - 离线消息存储与推送 ## 数据库设计 ### 核心数据模型 1. **用户表(Users)** - id: 主键 - studentId: 学号 - name: 姓名 - password: 加密密码 - isAdmin: 是否管理员 - createdAt: 创建时间 - updatedAt: 更新时间 2. **楼层表(Floors)** - id: 主键 - floorNumber: 楼层号 - description: 描述 3. **包间表(Rooms)** - id: 主键 - roomNumber: 包间号 - floorId: 所属楼层外键 - description: 描述 - status: 状态(available/maintenance) 4. **预约表(Reservations)** - id: 主键 - userId: 用户外键 - roomId: 包间外键 - startTime: 开始时间 - endTime: 结束时间 - status: 状态(pending/approved/rejected/canceled) - reason: 预约原因 5. **通知表(Notifications)** - id: 主键 - userId: 接收用户外键 - content: 内容 - isRead: 是否已读 - type: 通知类型 ## API 接口文档 ### 用户管理接口 #### 1. 用户登录 - **接口**:`POST /api/users/login` - **描述**:用户登录接口 - **请求参数**: ```json { "studentId": "string", "password": "string" } ``` - **响应示例**: ```json { "success": true, "data": { "studentId": "string", "name": "string", "isAdmin": boolean, "token": "string" } } ``` #### 2. 创建用户(管理员) - **接口**:`POST /api/users` - **描述**:创建新用户(需要管理员权限) - **请求参数**: ```json { "studentId": "string", "name": "string" } ``` - **响应示例**: ```json { "success": true, "data": { "studentId": "string", "name": "string", "isAdmin": false, "initialPassword": "string" } } ``` #### 3. 批量导入用户(管理员) - **接口**:`POST /api/users/import` - **描述**:通过Excel文件批量导入用户 - **请求**:multipart/form-data - **响应示例**: ```json { "success": true, "data": { "successCount": number, "errorCount": number, "results": array, "errors": array } } ``` ### 包间管理接口 #### 1. 创建包间 - **接口**:`POST /api/rooms/createRoom` - **描述**:创建新包间(需要管理员权限) - **请求参数**: ```json { "roomNumber": "string", "floorId": number, "description": "string", "capacity": number } ``` - **响应示例**: ```json { "success": true, "data": { "id": number, "roomNumber": "string", "floorId": number, "description": "string", "capacity": number, "status": "available" } } ``` #### 2. 获取所有包间 - **接口**:`GET /api/rooms/getAllRooms` - **描述**:获取所有包间信息(支持分页) - **查询参数**: - page: 页码 - pageSize: 每页数量 - **响应示例**: ```json { "success": true, "data": { "total": number, "items": [ { "id": number, "roomNumber": "string", "floor": { "id": number, "floorNumber": "string" }, "description": "string", "capacity": number, "status": "string" } ] } } ``` - **接口**:`POST /api/rooms` - **描述**:创建新包间(需要管理员权限) - **请求参数**: ```json { "roomNumber": "string", "description": "string", "defaultSeats": number } ``` - **响应示例**: ```json { "success": true, "data": { "id": number, "roomNumber": "string", "description": "string", "status": "available", "seats": [{ "id": number, "seatNumber": number, "status": "available" }] } } ``` #### 2. 获取所有包间 - **接口**:`GET /api/rooms` - **描述**:获取所有包间信息(支持分页、搜索和排序) - **查询参数**: - page: 页码 - pageSize: 每页数量 - search: 搜索关键词 - status: 包间状态 - sortBy: 排序字段 - order: 排序方向 - **响应示例**: ```json { "success": true, "data": { "rooms": [{ "id": number, "roomNumber": "string", "description": "string", "status": "string", "seats": array, "availableSeats": number }], "pagination": { "total": number, "currentPage": number, "totalPages": number, "pageSize": number } } } ``` ### 预约管理接口 #### 1. 创建预约 - **接口**:`POST /api/reservations` - **描述**:创建座位预约 - **请求参数**: ```json { "roomId": number, "seatId": number, "startTime": "datetime", "endTime": "datetime", "purpose": "string" } ``` - **响应示例**: ```json { "success": true, "data": { "id": number, "studentId": "string", "roomId": number, "seatId": number, "startTime": "datetime", "endTime": "datetime", "purpose": "string", "status": "pending" } } ``` #### 2. 审批预约 - **接口**:`PUT /api/reservations/:id/approve` - **描述**:审批预约请求(需要管理员权限) - **请求参数**: ```json { "status": "approved" | "rejected", "rejectReason": "string" } ``` - **响应示例**: ```json { "success": true, "data": { "id": number, "studentId": "string", "roomId": number, "seatId": number, "startTime": "datetime", "endTime": "datetime", "purpose": "string", "status": "string", "rejectReason": "string" } } ``` #### 3. 取消预约 - **接口**:`PUT /api/reservations/:id/cancel` - **描述**:取消预约(用户或管理员) - **响应示例**: ```json { "success": true, "message": "预约已取消" } ``` ## 数据库设计 ### User 表 | 字段名 | 类型 | 描述 | 约束 | |-----------|---------|----------|----------------| | studentId | STRING | 学号 | 主键 | | name | STRING | 姓名 | 非空 | | password | STRING | 密码 | 非空 | | isAdmin | BOOLEAN | 管理权限 | 默认false | | createdAt | DATE | 创建时间 | 自动生成 | | updatedAt | DATE | 更新时间 | 自动生成 | ### Room 表 | 字段名 | 类型 | 描述 | 约束 | |-------------|---------|------------|----------------------------------------| | id | INTEGER | 包间ID | 主键,自增 | | roomNumber | STRING | 包间编号 | 非空,唯一 | | status | ENUM | 包间状态 | 非空,可选值:available/maintenance | | description | STRING | 包间描述 | 可空 | | createdAt | DATE | 创建时间 | 自动生成 | | updatedAt | DATE | 更新时间 | 自动生成 | ### Seat 表 | 字段名 | 类型 | 描述 | 约束 | |-------------|---------|------------|----------------------------------------| | id | INTEGER | 座位ID | 主键,自增 | | roomId | INTEGER | 包间ID | 非空,外键关联Room表 | | seatNumber | INTEGER | 座位编号 | 非空 | | status | ENUM | 座位状态 | 非空,可选值:available/occupied/maintenance | | createdAt | DATE | 创建时间 | 自动生成 | | updatedAt | DATE | 更新时间 | 自动生成 | ### Reservation 表 | 字段名 | 类型 | 描述 | 约束 | |--------------|---------|------------|-------------------------------------------| | id | INTEGER | 预约ID | 主键,自增 | | studentId | STRING | 学生ID | 非空,外键关联User表 | | roomId | INTEGER | 包间ID | 非空,外键关联Room表 | | seatId | INTEGER | 座位ID | 非空,外键关联Seat表 | | startTime | DATE | 开始时间 | 非空 | | endTime | DATE | 结束时间 | 非空 | | status | ENUM | 预约状态 | 非空,可选值:pending/approved/rejected/cancelled | | purpose | STRING | 预约用途 | 非空 | | rejectReason | STRING | 拒绝原因 | 可空 | | createdAt | DATE | 创建时间 | 自动生成 | | updatedAt | DATE | 更新时间 | 自动生成 | ### Notification 表 | 字段名 | 类型 | 描述 | 约束 | |-----------|---------|------------|----------------------------------------| | id | INTEGER | 通知ID | 主键,自增 | | userId | STRING | 用户ID | 非空,外键关联User表 | | type | ENUM | 通知类型 | 非空,可选值:reservation/approval/system | | message | STRING | 通知内容 | 非空 | | isRead | BOOLEAN | 是否已读 | 非空,默认false | | createdAt | DATE | 创建时间 | 自动生成 | | updatedAt | DATE | 更新时间 | 自动生成 | ## 实时通知系统 系统使用WebSocket实现实时通知功能,主要特性包括: - 用户预约座位后,系统自动通知管理员进行审批 - 管理员审批预约后,系统自动通知用户审批结果 - 支持离线消息存储,用户上线后自动推送未读消息 - 使用Redis存储离线消息,确保消息不丢失 - 支持管理员广播通知功能 ## 安全机制 ### 密码处理 - 使用 bcrypt 进行密码加密存储 - 初始密码生成规则:姓氏拼音首字母(大写)+ 名字拼音(小写)+ @ + 学号 ### 身份认证 - 使用 JWT 进行身份验证 - Token 有效期为 24 小时 - 使用 Redis 实现令牌黑名单,支持令牌失效 ## 集成与测试 ### 测试策略 系统采用多层次测试策略,确保代码质量和功能稳定性: - **单元测试**:对各模块进行独立测试,验证核心逻辑正确性 - **集成测试**:测试系统各组件间的协作关系 - **API测试**:验证所有API接口的功能和性能 - **端到端测试**:模拟真实用户操作流程 ### 测试框架与工具 - **测试框架**:Jest - **API测试**:Supertest - **Mock工具**:Nock, Mockito - **测试覆盖率工具**:Istanbul/nyc - **持续集成**:GitHub Actions ### 测试目录结构 ``` ├── tests/ # 测试目录 │ ├── unit/ # 单元测试 │ │ ├── controllers/ # 控制器测试 │ │ ├── services/ # 服务层测试 │ │ └── middleware/ # 中间件测试 │ ├── integration/ # 集成测试 │ │ ├── api/ # API集成测试 │ │ └── database/ # 数据库集成测试 │ └── fixtures/ # 测试数据 ├── jest.config.js # Jest配置文件 └── .github/workflows/ # CI/CD配置 └── test.yml # 测试工作流 ``` ### 测试覆盖率要求 - **整体覆盖率**: ≥ 80% - **核心业务逻辑**: ≥ 90% - **API接口**: 100% ### 运行测试 ```bash # 运行所有测试 npm test # 运行单元测试 npm run test:unit # 运行集成测试 npm run test:integration # 生成测试覆盖率报告 npm run test:coverage ``` ### 持续集成配置 项目使用GitHub Actions实现持续集成,每次提交代码时自动执行以下任务: 1. 安装依赖 2. 运行代码质量检查(lint) 3. 执行单元测试和集成测试 4. 生成测试覆盖率报告 5. 构建项目 ### 集成测试示例 以下是API集成测试的典型示例: ```typescript // tests/integration/api/user.test.ts import request from 'supertest'; import app from '../../../src/app'; describe('用户管理API集成测试', () => { let adminToken: string; beforeAll(async () => { // 登录获取管理员token const response = await request(app) .post('/api/users/login') .send({ studentId: 'admin', password: 'admin123' }); adminToken = response.body.data.token; }); test('创建新用户', async () => { const response = await request(app) .post('/api/users') .set('Authorization', `Bearer ${adminToken}`) .send({ studentId: 'test123', name: '测试用户' }); expect(response.status).toBe(200); expect(response.body.success).toBe(true); expect(response.body.data.studentId).toBe('test123'); }); // 更多测试用例... }); ``` ### 测试环境配置 测试环境使用独立的数据库和Redis实例,通过环境变量配置: ```env # 测试环境配置示例 NODE_ENV=test DB_HOST=localhost DB_PORT=3306 DB_NAME=library_reservation_test DB_USER=test_user DB_PASSWORD=test_password REDIS_HOST=localhost REDIS_PORT=6379 ``` ## 部署说明 ### 环境要求 - **Node.js**: v14.0 或以上 - **MySQL**: v8.0 或以上 - **Redis**: v6.0 或以上 ### 安装步骤 1. 克隆项目代码 2. 安装依赖:`npm install` 3. 配置环境变量:复制 `.env.example` 为 `.env` 并填写配置 4. 初始化数据库:运行数据库迁移脚本 5. 启动服务:`npm run dev`(开发环境)或 `npm run start`(生产环境) ### 环境变量配置 ```env PORT=3000 DB_HOST=localhost DB_PORT=3306 DB_NAME=library_reservation DB_USER=root DB_PASSWORD=your_password REDIS_HOST=localhost REDIS_PORT=6379 JWT_SECRET=your_jwt_secret ``` ### 测试环境部署 1. 配置测试环境变量文件 `.env.test` 2. 初始化测试数据库: ```bash npm run db:init:test ``` 3. 运行测试: ```bash npm test ``` ## 使用说明 ### 管理员功能 1. 用户管理 - 批量导入用户:使用提供的Excel模板 - 重置用户密码 - 管理用户权限 2. 包间管理 - 创建新包间并设置座位数量 - 修改包间状态(可用/维护中) - 查看包间使用情况 3. 预约管理 - 审批预约申请 - 查看预约历史 - 取消预约 ### 用户功能 1. 账户管理 - 修改个人信息 - 修改密码 - 查看通知 2. 预约功能 - 查看包间和座位状态 - 预约座位 - 取消预约 - 查看预约历史 ## 测试与质量保证 ### 代码质量检查 项目使用ESLint和Prettier确保代码质量和一致性: ```bash # 运行代码检查 npm run lint # 自动修复格式问题 npm run lint:fix ``` ### 性能测试 系统关键接口进行性能测试,确保在高并发下的稳定性: - 使用Artillery进行负载测试 - 目标:支持100并发用户,响应时间<500ms ### 安全测试 - 定期进行代码安全扫描 - 对所有输入进行严格验证 - 敏感数据加密存储 - 定期更新依赖库,修复安全漏洞