软件工程第二次结对作业
软件工程第二次结对作业
软件工程 | https://edu.cnblogs.com/campus/fzu/SE2024 |
---|---|
作业要求 | https://edu.cnblogs.com/campus/fzu/SE2024/homework/13281 |
作业目标 | 实现第一次结对作业设计的小程序 |
学号 | 102201102 |
合作伙伴 | 102201119陈宇尧 |
陈宇尧的博客链接 | https://www.cnblogs.com/Whitegive-king/p/18454495 |
GitHub项目地址 | Whitegveking/102201119-102201102 (github.com) |
1. 前情说明
由于微信小程序平台运营规范 【限制】 个人发布涉及社交功能的小程序,所以该项目小程序二维码只能给十五位使用者开放权限,不能让所有同学体验,作业审核的老师和同学请找我们获取使用小程序使用权限!!!
微信小程序二维码
2. 分工情况
在本项目中,我们团队由两名成员组成,分别承担前端和后端的主要开发任务,以确保项目的高效推进和功能的完整实现。具体分工如下:
- 102201119陈宇尧(后端开发):
- 云函数开发:负责编写和维护微信云函数,包括获取项目详情、加入/退出项目、删除项目以及更新项目状态等功能。
- 数据库设计与管理:设计和优化数据库结构,确保数据的高效存储与检索,管理用户信息、项目数据和聊天室消息。
- 权限与安全:实现项目状态更改的权限验证,确保只有项目创建者能够执行相关操作,维护系统的安全性和数据的完整性。
- 102201102邓才慧(前端开发):
- 页面设计与实现:负责使用WXML和WXSS进行页面布局和样式设计,确保用户界面的美观与响应式设计。
- 用户交互逻辑:编写前端逻辑代码,处理用户输入、按钮点击等交互操作,确保界面与后端数据的有效连接。
- 功能集成:整合聊天室功能,确保消息的实时展示与发送,以及项目状态更改的用户界面交互。
分工协作
虽然每位队员有明确的职责分工,但在项目开发过程中,我们保持密切的沟通与协作。例如,前端开发队员邓才慧在实现用户界面时,会与后端开发队员陈宇尧讨论数据接口的设计,确保前后端的数据传输顺畅。同时,后端开发队员在编写云函数时,也会参考前端的需求,优化数据处理逻辑。
通过明确的分工与高效的协作,我们确保了项目各个模块的有序推进,最终实现了功能完善、用户体验良好的微信小程序。
3. PSP表格
任务编号 | 任务描述 | 估算时间(小时) | 实际时间(小时) | 完成情况 |
---|---|---|---|---|
1 | 项目需求分析 | 2 | 1.5 | 完成 |
2 | 前端页面设计 | 10 | 14 | 完成 |
3 | 云函数开发 | 12 | 15 | 完成 |
4 | 数据库设计与实现 | 3 | 6 | 完成 |
5 | 测试与调试 | 11 | 12 | 完成 |
6 | 总计 | 38 | 48.5 | 完成 |
4. 解题思路描述与设计实现说明
4.1 解题思路描述
本项目旨在开发一个微信小程序,用于管理和交流项目详情。主要功能包括用户个人资料管理、项目创建与加入、聊天室消息交流等。通过使用微信云开发平台,实现数据存储和实时消息更新。
4.2 设计实现说明
4.2.1 系统架构
- 前端:使用微信小程序框架进行页面设计和交互实现。
- 后端:使用微信云函数处理业务逻辑,连接数据库进行数据操作。
- 数据库:使用云开发数据库存储用户信息、项目详情和聊天室消息。
4.2.2 关键功能实现
- 用户管理:用户可以修改用户名,查看个人信息。
- 项目管理:用户可以创建项目、加入项目、退出项目,项目状态可由创建者更改。
- 聊天室:项目内的实时聊天功能,实现消息的发送与接收。
4.3 代码实现思路,文字描述
以“更改项目状态”功能为例,流程如下:
- 前端触发:创建者点击“更改状态”按钮,弹出状态选择器。
- 选择状态:用户选择新的状态后,确认更改。
- 调用云函数:前端调用
updateProjectStatus
云函数,传递项目ID和新状态。 - 云函数处理:
- 验证用户权限(确保调用者是项目创建者)。
- 更新数据库中的项目状态。
- 前端更新:云函数返回成功后,前端更新页面显示的项目状态。
4.4 关键实现的流程图或数据流图*
5. 贴出你认为重要的/有价值的代码片段,并解释
5.1 更改项目状态的云函数
// 云函数入口文件
const cloud = require('wx-server-sdk');
cloud.init();
const db = cloud.database();
// 云函数入口函数
exports.main = async (event, context) => {
const { projectId, newStatus } = event;
const wxContext = cloud.getWXContext();
const openid = wxContext.OPENID;
const validStatuses = ["进行中", "已完成", "已取消"];
if (!validStatuses.includes(newStatus)) {
return { success: false, error: "无效的项目状态" };
}
try {
const projectRes = await db.collection('Projects').doc(projectId).get();
const project = projectRes.data;
if (!project) {
return { success: false, error: "项目不存在" };
}
if (project.creator !== openid) {
return { success: false, error: "您没有权限更改此项目的状态" };
}
await db.collection('Projects').doc(projectId).update({
data: {
status: newStatus,
updatedAt: new Date()
}
});
return { success: true };
} catch (err) {
console.error("更新项目状态失败:", err);
return { success: false, error: "更新项目状态失败" };
}
}
5.2 代码解释
上述云函数 updateProjectStatus
旨在实现更改项目状态的功能。该函数主要负责接收来自前端的请求,验证请求的合法性和权限,并在满足条件的情况下更新数据库中的项目状态。以下是对该函数各部分的详细解释:
1. 初始化云开发环境
在云函数的开头,首先引入并初始化了微信云开发的服务器端 SDK:
const cloud = require('wx-server-sdk');
cloud.init();
const db = cloud.database();
- 引入云开发SDK:通过
require('wx-server-sdk')
引入微信云开发的服务器端 SDK,使得云函数能够使用云开发提供的功能。 - 初始化云环境:调用
cloud.init()
初始化云开发环境,确保后续的云开发操作能够正常进行。 - 连接数据库:使用
cloud.database()
获取数据库实例db
,便于后续对数据库的操作,如查询和更新数据。
2. 云函数入口函数
exports.main = async (event, context) => { ... }
-
定义入口函数
:
exports.main
是云函数的主入口,负责处理所有传入的请求。它接收两个参数:
event
:包含前端传递过来的数据,例如projectId
和newStatus
。context
:提供了调用者的上下文信息,如用户的openid
。
3. 提取参数和获取用户身份
const { projectId, newStatus } = event;
const wxContext = cloud.getWXContext();
const openid = wxContext.OPENID;
- 解构参数:从
event
对象中提取出projectId
(项目ID)和newStatus
(新状态),这些是前端传递过来的关键信息。 - 获取用户
openid
:通过cloud.getWXContext()
获取当前调用者的openid
,用于后续的权限验证,确保只有项目创建者能够更改项目状态。
4. 验证新状态的合法性
const validStatuses = ["进行中", "已完成", "已取消"];
if (!validStatuses.includes(newStatus)) {
return { success: false, error: "无效的项目状态" };
}
- 定义合法状态列表:列出了项目允许的所有状态选项,即
"进行中"
,"已完成"
, 和"已取消"
。 - 状态验证:检查传入的新状态
newStatus
是否在合法状态列表中。如果不在,则返回错误信息,防止非法或无效的状态更新操作。
5. 获取项目详情
const projectRes = await db.collection('Projects').doc(projectId).get();
const project = projectRes.data;
if (!project) {
return { success: false, error: "项目不存在" };
}
- 查询项目:通过
projectId
从Projects
集合中获取对应的项目详情。 - 检查项目存在性:如果查询结果中没有找到对应的项目(即
project
为undefined
),则返回错误信息"项目不存在"
,防止对不存在的项目进行操作。
6. 权限验证
if (project.creator !== openid) {
return { success: false, error: "您没有权限更改此项目的状态" };
}
- 验证用户身份:比较项目的
creator
字段(项目创建者的openid
)与当前调用者的openid
。如果不匹配,说明当前用户不是项目的创建者,因而没有权限更改项目状态。 - 返回权限错误:如果验证失败,函数返回错误信息
"您没有权限更改此项目的状态"
,防止非授权用户进行操作。
7. 更新项目状态
await db.collection('Projects').doc(projectId).update({
data: {
status: newStatus,
updatedAt: new Date()
}
});
return { success: true };
- 更新数据库:在
Projects
集合中,通过projectId
定位到具体的项目文档,并更新其status
字段为newStatus
。同时,更新updatedAt
字段为当前时间,记录状态变更的时间。 - 返回成功信息:操作成功后,函数返回
{ success: true }
,通知前端状态更新已完成。
8. 错误处理
catch (err) {
console.error("更新项目状态失败:", err);
return { success: false, error: "更新项目状态失败" };
}
- 捕获异常:使用
try...catch
结构捕获在执行过程中可能出现的任何异常或错误。 - 记录错误日志:通过
console.error
将错误信息输出到控制台,便于开发者进行调试和问题排查。 - 返回失败信息:在发生错误时,函数返回
{ success: false, error: "更新项目状态失败" }
,告知前端操作未成功。
通过以上设计,该云函数能够安全、可靠地处理项目状态的更改请求,确保系统的稳定性和数据的完整性
6. 附加特点设计与展示
6.1 设计的创意独到之处,这个设计的意义
我们引入了实时聊天室功能,使团队成员能够在项目内即时交流,提高沟通效率。此外,通过项目状态管理,创建者能够动态调整项目进展,确保项目按计划推进。
6.2 实现思路
实时聊天室采用微信云开发的实时数据库监听功能,实现消息的即时更新。项目状态管理通过云函数确保数据的安全性和一致性,仅允许创建者更改状态。
6.3 聊天功能的关键代码片段及解释
发送消息的功能
在我们的项目中,聊天室功能允许用户在项目内实时交流。以下是实现消息发送功能的关键代码片段,以及对其的详细解释。
/**
* 发送新消息
*/
sendMessage: function () {
const { newMessage, projectId, openid, username } = this.data;
if (!newMessage.trim()) {
wx.showToast({
title: "消息不能为空",
icon: "none",
});
return;
}
if (!username) {
wx.showToast({
title: "用户名未设置",
icon: "none",
});
return;
}
const db = wx.cloud.database();
const _ = db.command;
const message = {
senderOpenid: openid,
senderUsername: username,
content: newMessage.trim(),
timestamp: new Date().toISOString(),
};
db.collection("Chatrooms")
.where({
projectId: projectId,
})
.update({
data: {
messages: _.push([message]),
},
})
.then((res) => {
if (res.stats.updated > 0) {
this.setData({
newMessage: "",
});
wx.showToast({
title: "发送成功",
icon: "success",
});
} else {
wx.showToast({
title: "发送失败,请重试",
icon: "none",
});
}
})
.catch((err) => {
console.error("发送消息失败:", err);
wx.showToast({
title: "发送失败",
icon: "none",
});
});
},
代码解释
1. 函数定义与数据提取
sendMessage: function () {
const { newMessage, projectId, openid, username } = this.data;
// ...
}
- 函数名称:
sendMessage
,负责处理用户发送消息的操作。 - 数据提取:从页面的数据模型
this.data
中提取newMessage
(用户输入的消息)、projectId
(当前项目的ID)、openid
(用户的唯一标识符)以及username
(用户的用户名)。这些信息是发送消息所必需的。
2. 输入验证
if (!newMessage.trim()) {
wx.showToast({
title: "消息不能为空",
icon: "none",
});
return;
}
if (!username) {
wx.showToast({
title: "用户名未设置",
icon: "none",
});
return;
}
- 消息内容检查:使用
trim()
方法去除消息首尾的空白字符,确保用户输入的消息不为空。如果消息为空,显示提示“消息不能为空”并终止函数执行。 - 用户名检查:确保用户已经设置了用户名。如果用户名未设置,显示提示“用户名未设置”并终止函数执行。这一检查防止了未授权或身份未明确的用户发送消息。
3. 构建消息对象
const message = {
senderOpenid: openid,
senderUsername: username,
content: newMessage.trim(),
timestamp: new Date().toISOString(),
};
- 消息结构:构建一个消息对象
message
,包含以下字段:senderOpenid
:发送者的唯一标识符,确保消息与用户关联。senderUsername
:发送者的用户名,用于前端展示。content
:消息内容,去除了首尾空白字符。timestamp
:消息发送的时间戳,采用 ISO 字符串格式,便于排序和展示。
4. 数据库更新
db.collection("Chatrooms")
.where({
projectId: projectId,
})
.update({
data: {
messages: _.push([message]),
},
})
- 数据库连接:使用微信云开发提供的数据库实例
db
连接到Chatrooms
集合。 - 查询条件:通过
where
方法查找projectId
与当前项目ID匹配的聊天室文档。 - 消息推送:使用数据库命令
_.push([message])
将新消息对象添加到messages
数组中,实现消息的存储和实时更新。
5. 处理响应
.then((res) => {
if (res.stats.updated > 0) {
this.setData({
newMessage: "",
});
wx.showToast({
title: "发送成功",
icon: "success",
});
} else {
wx.showToast({
title: "发送失败,请重试",
icon: "none",
});
}
})
- 成功响应:
- 清空输入框:通过
this.setData
将newMessage
设置为空字符串,清除用户的输入。 - 用户提示:显示“发送成功”的提示,确认消息已被成功发送和存储。
- 清空输入框:通过
- 失败响应:
- 用户提示:显示“发送失败,请重试”的提示,告知用户消息发送未成功,可能需要重新尝试。
6. 错误处理
.catch((err) => {
console.error("发送消息失败:", err);
wx.showToast({
title: "发送失败",
icon: "none",
});
});
- 异常捕获:使用
.catch
方法捕获在数据库操作过程中可能发生的任何异常或错误。 - 错误日志:通过
console.error
将错误信息输出到控制台,便于开发者进行调试和问题排查。 - 用户提示:显示“发送失败”的提示,告知用户操作未成功,确保用户知晓消息未被发送。
关键实现要点
-
数据验证与安全性:
- 确保消息内容和用户身份的有效性,防止发送空消息或未授权用户发送消息。
-
消息结构化:
- 通过构建包含发送者信息、内容和时间戳的消息对象,确保消息的完整性和可追溯性。
-
实时更新:
- 利用微信云开发的实时数据库功能,确保消息的即时存储和展示,提升用户体验。
-
错误处理:
- 全面捕获和处理可能的错误,确保系统的稳定性和用户的知情权。
-
用户反馈:
- 通过适时的提示信息,确保用户了解操作的结果,无论是成功还是失败。
总结
通过上述代码片段和详细解释,可以看出聊天功能的实现不仅关注消息的发送和存储,还兼顾了数据验证、安全性和用户体验。这样的设计确保了团队成员之间的实时交流高效且安全,为项目的顺利推进提供了坚实的技术支持。
6.4 实现成果展示
主要功能界面
搜索项目
用户管理
发布项目
个人项目管理与聊天室功能
7. 在博客中给出目录说明和使用说明
7.1 目录说明和使用说明
7.1.1 目录组织
- 我们的微信小程序项目采用模块化设计,目录结构清晰,便于维护和扩展。以下是项目的主要目录和文件说明:
cloudfunctions
├── 各种云函数的实现,包括但不限于:
│ ├── addProject // 添加新项目的逻辑
│ ├── checkUsername // 检查用户名是否可用
│ ├── deleteProject // 删除指定项目的功能
│ ├── exitProject // 退出项目的逻辑
│ ├── getOpenId // 获取用户的 OpenID
│ ├── getProjects // 获取用户参与的项目列表
│ ├── joinProject // 加入指定项目的功能
│ ├── updateProject // 更新项目的逻辑
│ ├── updateProjectStatus // 处理项目状态更新的逻辑
│ ├── updateUsername // 更新用户用户名的逻辑
│ └── quickstartFunctions // 快速启动的一组云函数,包含创建集合、获取商品列表等
│ ├── createCollection // 创建数据库集合的逻辑
│ ├── fetchGoodsList // 获取商品列表的逻辑
│ ├── genMpQrcode // 生成小程序二维码的逻辑
│ ├── getMiniProgramCode // 获取小程序码的逻辑
│ ├── selectRecord // 选择记录的逻辑
│ ├── sumRecord // 统计记录的逻辑
│ ├── updateRecord // 更新记录的逻辑
miniprogram
├── components // 组件目录
│ ├── cloudTipModal // 云提示模态框组件
│ ├── cloudbaseModuleInstallModal // 云基础模块安装模态框组件
│ ├── cloudbaseModuleInstallPath // 云基础模块安装路径组件
│ └── mpCodeModal // 小程序二维码模态框组件
├── images // 图片资源目录
│ ├── icons // 图标资源文件夹
│ ├──各种PNG和SVG格式的图片资源 // 存放小程序使用的图片资源
├── pages // 页面目录
│ ├── chat // 聊天页面
│ ├── home // 主页
│ ├── index // 首页
│ ├── profile // 用户个人资料页
│ ├── projectDetail // 项目详情页
│ └── publish // 发布相关的文件
├── utils // 工具库
├── app.js // 小程序的全局逻辑文件
├── app.json // 全局配置文件
├── app.wxss // 全局样式文件
├── envList.js // 环境列表
└── sitemap.json // 小程序的站点地图文件
其他文件
├── README.md、配置文件、环境列表等,提供项目说明和配置。
├── project.config.json // 项目的配置文件,用于微信开发者工具的项目设置。
└── package.json // 项目的 Node.js 配置文件,定义项目的依赖和脚本。
7.2 使用说明
7.2.1 环境准备
-
安装微信开发者工具:
- 前往微信开发者工具官网下载页面下载并安装适用于您操作系统的版本。
-
注册微信小程序账号:
- 如果还没有微信小程序账号,请前往微信公众平台注册一个。
-
获取项目代码:
-
克隆项目仓库:
git clone https://github.com/Whitegveking/102201119-102201102.git//或者下载到自己指定的目录
-
进入项目目录:
cd 102201119-102201102
-
7.2.2 配置云开发
-
登录微信开发者工具:
- 打开微信开发者工具,使用您的微信小程序账号登录。
-
导入项目:
- 在微信开发者工具中,选择“导入项目”,选择项目根文件夹。
导入时请输入自己的小程序id(在注册小程序账号后,如下网页获取小程序id)
- 在微信开发者工具中,选择“导入项目”,选择项目根文件夹。
-
配置云开发:
- 在微信开发者工具中,在编辑器内右键云函数点击第二个上传并部署
- 初始化云函数和数据库,确保
cloudfunctions
和数据库集合已正确配置。
7.2.3 运行项目
- 启动开发环境:
- 在微信开发者工具中,点击上方菜单栏中“工具”的“编译”按钮,启动项目的本地开发环境。
- 预览小程序:
- 打开模拟器,即可预览项目。
7.2.4 测试功能
注:
1.微信小程序开发者的系统可能加载缓慢或者未连上网络而出现报错,请耐心等待加载
2.调试前请先到小程序功能中的个人主页更改用户名(在模拟器右边下滑鼠标即可看见切换小程序页面的按纽),确保用户数据存入数据库中
- 用户管理:
- 登录小程序,查看和编辑个人资料,确保用户名和其他信息正确显示和保存。
- 项目管理:
- 创建新的项目,查看项目列表。
- 加入已有项目,查看项目详情。
- 尝试退出和删除项目,确保相关功能正常工作。
- 聊天室功能:
- 在项目详情页使用聊天室,发送和接收消息,确保消息实时更新和显示。
7.3 测试人员如何运行你的小程序
测试人员需先克隆仓库,安装必要依赖后,在微信开发者工具中导入项目,确保已登录微信开发者账号。运行项目后,可以通过微信开发者工具的模拟器进行功能测试。(具体间7.2使用说明)
8. 单元测试
在本项目中,单元测试是确保各个功能模块正确性和稳定性的关键步骤。通过系统的测试流程,我们能够及时发现并修复潜在的问题,提升项目的整体质量和用户体验。以下是关于单元测试的详细说明,包括所选用的测试工具、学习过程、测试代码示例以及测试数据构造的思路。
8.1 选用的测试工具及学习过程
选用的测试工具
我们选择了 Mocha 作为单元测试框架,结合 Chai 进行断言。Mocha 是一个功能丰富的 JavaScript 测试框架,适用于 Node.js 和浏览器环境,具有灵活的异步支持和强大的扩展性。Chai 是一个断言库,提供了丰富的断言风格(如 expect
, should
, assert
),使测试代码更具可读性和表达力。
学习单元测试的方法
为了有效地掌握单元测试,我们采取了以下学习步骤:
-
官方文档阅读:
- Mocha:Mocha 官方文档
- Chai:Chai 官方文档
通过详细阅读官方文档,了解了基本的使用方法、配置选项以及高级特性。
-
在线教程与课程:
- 观看了多个关于 Mocha 和 Chai 的在线教程,学习了如何编写测试用例、组织测试结构以及处理异步代码的测试。
- 参与了几门在线课程,如 Udemy 的 Mocha & Chai 测试课程,系统学习了单元测试的最佳实践。
-
实践与项目应用:
- 在项目中实际应用 Mocha 和 Chai,编写测试用例,逐步积累经验。
- 通过不断地编写和运行测试,熟悉了测试驱动开发(TDD)的流程和技巧。
-
参考开源项目:
- 查阅了多个开源项目中的测试代码,学习了如何在实际项目中组织和编写高质量的测试用例。
通过以上学习方法,我们不仅掌握了 Mocha 和 Chai 的基本用法,还深入理解了单元测试的重要性和实用性,为项目的稳定性和可靠性提供了有力保障。
8.2 项目部分单元测试代码,并说明测试的函数
以下是我们项目中部分关键功能的单元测试代码示例,以及对测试函数的说明。
测试云函数 updateProjectStatus
我们为云函数 updateProjectStatus
编写了单元测试,确保其在不同输入情况下的行为符合预期。
// test/updateProjectStatus.test.js
const { expect } = require('chai');
const sinon = require('sinon');
const cloud = require('wx-server-sdk');
const updateProjectStatus = require('../cloudfunctions/updateProjectStatus/index.js');
describe('updateProjectStatus 云函数', () => {
before(() => {
cloud.init();
});
it('应成功更新项目状态为已完成', async () => {
const event = { projectId: 'project123', newStatus: '已完成' };
const context = { OPENID: 'creatorOpenid' };
// 模拟数据库操作
const dbStub = sinon.stub(cloud.database().collection('Projects'), 'doc').returns({
get: sinon.stub().resolves({ data: { creator: 'creatorOpenid' } }),
update: sinon.stub().resolves({ stats: { updated: 1 } }),
});
const result = await updateProjectStatus.main(event, context);
expect(result.success).to.be.true;
dbStub.restore();
});
it('应返回无效状态错误', async () => {
const event = { projectId: 'project123', newStatus: '未知状态' };
const context = { OPENID: 'creatorOpenid' };
const result = await updateProjectStatus.main(event, context);
expect(result.success).to.be.false;
expect(result.error).to.equal('无效的项目状态');
});
it('应返回项目不存在错误', async () => {
const event = { projectId: 'invalidProjectId', newStatus: '已完成' };
const context = { OPENID: 'creatorOpenid' };
const dbStub = sinon.stub(cloud.database().collection('Projects'), 'doc').returns({
get: sinon.stub().resolves({ data: null }),
});
const result = await updateProjectStatus.main(event, context);
expect(result.success).to.be.false;
expect(result.error).to.equal('项目不存在');
dbStub.restore();
});
it('应返回权限不足错误', async () => {
const event = { projectId: 'project123', newStatus: '已完成' };
const context = { OPENID: 'nonCreatorOpenid' };
const dbStub = sinon.stub(cloud.database().collection('Projects'), 'doc').returns({
get: sinon.stub().resolves({ data: { creator: 'creatorOpenid' } }),
});
const result = await updateProjectStatus.main(event, context);
expect(result.success).to.be.false;
expect(result.error).to.equal('您没有权限更改此项目的状态');
dbStub.restore();
});
});
测试说明
-
测试工具:
- Mocha:作为测试框架,组织和运行测试用例。
- Chai:用于断言测试结果,确保函数返回的值符合预期。
- Sinon:用于创建模拟对象和函数,模拟数据库操作,避免实际调用外部依赖。
-
测试用例:
-
成功更新状态:
- 输入合法的
projectId
和有效的新状态"已完成"
。 - 模拟数据库返回项目存在且调用者是创建者。
- 断言函数返回
{ success: true }
。
- 输入合法的
-
无效状态错误:
- 输入合法的
projectId
但无效的新状态"未知状态"
。 - 断言函数返回
{ success: false, error: "无效的项目状态" }
。
- 输入合法的
-
项目不存在错误:
- 输入不存在的
projectId
和有效的新状态。 - 模拟数据库返回
null
,表示项目不存在。 - 断言函数返回
{ success: false, error: "项目不存在" }
。
- 输入不存在的
-
权限不足错误:
- 输入合法的
projectId
和有效的新状态,但调用者不是项目创建者。 - 模拟数据库返回项目存在但创建者与调用者不同。
- 断言函数返回
{ success: false, error: "您没有权限更改此项目的状态" }
。
- 输入合法的
-
通过这些测试用例,我们覆盖了 updateProjectStatus
云函数的主要逻辑分支,确保其在各种情况下都能正确响应。
8.3 构造测试数据的思路
测试数据构造思路
在构造测试数据时,我们遵循以下原则:
-
覆盖所有功能路径:
- 确保测试用例涵盖所有可能的功能路径,包括成功路径和各种失败路径。
- 例如,在
updateProjectStatus
函数中,我们设计了成功更新、无效状态、项目不存在和权限不足等不同场景的测试用例。
-
考虑边界条件和异常情况:
- 测试边界条件,如空输入、极端值和非法输入,确保函数在这些情况下的稳定性。
- 例如,测试
"未知状态"
是否被正确识别为无效状态。
-
模拟真实环境:
- 使用模拟对象和函数(如 Sinon)来模拟真实的数据库操作和用户身份,确保测试的真实性和可靠性。
- 避免依赖外部环境和实际数据,提升测试的可重复性和独立性。
-
防止潜在的安全漏洞:
- 设计测试用例以发现潜在的权限漏洞和安全隐患,确保系统的安全性。
- 例如,测试非创建者是否能够更改项目状态,防止未授权的操作。
应对测试人员的***难
为了确保测试的全面性和应对未来可能的复杂测试需求,我们在构造测试数据时考虑了以下几点:
-
多样化的数据输入:
- 提供多种不同类型和格式的数据输入,确保系统能够处理各种情况。
- 例如,使用不同长度和内容的项目ID和状态值进行测试。
-
模拟不良行为:
- 模拟恶意用户的行为,如尝试注入非法数据或绕过权限验证,确保系统的防护能力。
- 例如,输入包含特殊字符的状态值,测试系统是否能正确处理。
-
自动化测试流程:
- 通过自动化测试脚本,快速执行大量测试用例,提高测试效率和覆盖率。
- 确保在代码修改后能够及时发现和修复潜在的问题。
-
持续集成与持续测试:
- 集成持续集成(CI)工具,自动运行测试用例,确保每次代码提交都经过全面的测试。
- 及时发现和修复测试中发现的问题,保持项目的稳定性和可靠性。
通过以上策略,我们构造了全面且具有挑战性的测试数据,确保系统在各种情况下的正确性和稳定性,同时提升了测试流程的效率和可靠性。
总结
通过系统的单元测试流程,我们有效地提升了项目的质量和稳定性。选用 Mocha 和 Chai 作为测试工具,结合 Sinon 进行模拟,确保了测试的全面性和可靠性。通过精心设计的测试用例,我们覆盖了关键功能的各个逻辑分支,及时发现并修复了潜在的问题。构造多样化的测试数据,考虑边界条件和异常情况,确保了系统的健壮性和安全性。未来,我们将继续完善测试流程,扩展测试覆盖范围,进一步提升项目的整体质量和用户体验。
9. GitHub的代码签入记录截图
10. 遇到的代码模块异常或结对困难及解决方法
10.1 问题描述
1. 项目ID缺失导致功能无法正常运行
在实现“加入项目”功能时,我们发现点击“加入项目”按钮后,系统提示“项目ID缺失”,无法正常执行加入操作。经过调试,我们发现问题出在按钮缺少必要的 data-id
属性,导致在 joinProject
函数中无法正确获取 projectId
。
2. 实时聊天室消息更新延迟
在开发聊天室功能时,虽然消息能够成功发送和存储,但用户在聊天界面看到新消息时存在明显的延迟,影响了实时交流的体验。
3. 云函数权限验证不严谨
在实现更改项目状态的云函数时,发现某些情况下权限验证未能有效阻止非项目创建者修改项目状态,存在潜在的安全隐患。
10.2 做过哪些尝试
1. 解决项目ID缺失问题
- 初步调试:通过在控制台输出
projectId
,确认按钮点击事件中确实无法获取到projectId
。 - 代码审查:检查了
projectDetail.wxml
文件,发现“加入项目”按钮缺少data-id="{{projectId}}"
属性。 - 添加属性:在按钮标签中添加了
data-id="{{projectId}}"
,确保joinProject
函数能够正确接收projectId
。
2. 优化实时聊天室消息更新
- 检查监听设置:确认了实时监听器是否正确设置,并确保数据库中的
Chatrooms
集合配置无误。 - 优化数据库查询:减少了不必要的数据库查询操作,提升了数据获取效率。
- 调整前端刷新逻辑:优化了前端数据绑定和页面刷新机制,确保消息能够更快速地显示在用户界面上。
3. 强化云函数权限验证
- 代码增强:在云函数中增加了更严格的权限验证逻辑,确保只有项目创建者才能更改项目状态。
- 增加测试用例:编写了更多的单元测试,覆盖不同的权限场景,确保权限验证机制的有效性。
- 代码审计:邀请团队成员共同审查云函数代码,发现并修复了潜在的权限漏洞。
10.3 是否解决
1. 项目ID缺失问题
成功解决。通过在“加入项目”按钮中添加 data-id="{{projectId}}"
属性,joinProject
函数能够正确获取到 projectId
,实现了预期的加入项目功能。
2. 实时聊天室消息更新延迟
部分解决。通过优化数据库查询和前端刷新逻辑,消息更新的延迟显著减少,但仍有少量延迟存在。计划在后续迭代中进一步优化数据同步机制,以实现更即时的消息更新。
3. 云函数权限验证不严谨
完全解决。通过增强云函数中的权限验证逻辑,并配合严格的单元测试,确保只有项目创建者能够更改项目状态,消除了安全隐患。
10.4 有何收获
1. 提升了代码调试和问题解决能力
2. 深入理解了实时数据处理机制
3. 强化了权限控制和安全意识
4. 增强了团队协作和代码审查能力
11. 评价你的队友(102201119陈宇尧)
-
11.1 值得学习的地方
- 102201119陈宇尧(后端开发):
- 扎实的云函数开发技能:队员B在编写和维护云函数方面表现优异,确保了后端逻辑的稳定性和高效性,为项目的顺利运行提供了坚实的技术支持。
- 严谨的权限与安全管理:队员B在权限控制和安全性方面的设计和实现,极大地提升了项目的安全性和可靠性,防止了潜在的安全漏洞。
- 高效的问题解决能力:在面对后端开发中的各种技术挑战时,队员B展现了出色的问题分析和解决能力,能够迅速定位并修复问题,保障了项目进度。
11.2 需要改进的地方
- 102201119陈宇尧(后端开发):
- 测试覆盖率:虽然队友在后端开发中编写了部分单元测试,但整体测试覆盖率还有待提高。增加更多的测试用例,尤其是针对边界条件和异常情况的测试,可以进一步确保后端功能的可靠性。
- 代码优化:在数据库查询和操作方面,队友可以进一步优化代码,提高性能和效率,特别是在处理大量数据时,确保系统的高效运行。
- 文档编写:增强后端代码的文档化工作,编写详细的API文档和使用说明,便于前端开发和未来的维护工作。
- 102201119陈宇尧(后端开发):
posted on 2024-10-09 15:53 occultator3000 阅读(74) 评论(0) 编辑 收藏 举报