occultator3000

导航

软件工程第二次结对作业

软件工程第二次结对作业

软件工程 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 代码实现思路,文字描述

以“更改项目状态”功能为例,流程如下:

  1. 前端触发:创建者点击“更改状态”按钮,弹出状态选择器。
  2. 选择状态:用户选择新的状态后,确认更改。
  3. 调用云函数:前端调用updateProjectStatus云函数,传递项目ID和新状态。
  4. 云函数处理
    • 验证用户权限(确保调用者是项目创建者)。
    • 更新数据库中的项目状态。
  5. 前端更新:云函数返回成功后,前端更新页面显示的项目状态。

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:包含前端传递过来的数据,例如 projectIdnewStatus
    • 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: "项目不存在" };
}
  • 查询项目:通过 projectIdProjects 集合中获取对应的项目详情。
  • 检查项目存在性:如果查询结果中没有找到对应的项目(即 projectundefined),则返回错误信息 "项目不存在",防止对不存在的项目进行操作。

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.setDatanewMessage 设置为空字符串,清除用户的输入。
    • 用户提示:显示“发送成功”的提示,确认消息已被成功发送和存储。
  • 失败响应
    • 用户提示:显示“发送失败,请重试”的提示,告知用户消息发送未成功,可能需要重新尝试。
6. 错误处理
.catch((err) => {
  console.error("发送消息失败:", err);
  wx.showToast({
    title: "发送失败",
    icon: "none",
  });
});
  • 异常捕获:使用 .catch 方法捕获在数据库操作过程中可能发生的任何异常或错误。
  • 错误日志:通过 console.error 将错误信息输出到控制台,便于开发者进行调试和问题排查。
  • 用户提示:显示“发送失败”的提示,告知用户操作未成功,确保用户知晓消息未被发送。

关键实现要点

  1. 数据验证与安全性

    • 确保消息内容和用户身份的有效性,防止发送空消息或未授权用户发送消息。
  2. 消息结构化

    • 通过构建包含发送者信息、内容和时间戳的消息对象,确保消息的完整性和可追溯性。
  3. 实时更新

    • 利用微信云开发的实时数据库功能,确保消息的即时存储和展示,提升用户体验。
  4. 错误处理

    • 全面捕获和处理可能的错误,确保系统的稳定性和用户的知情权。
  5. 用户反馈

    • 通过适时的提示信息,确保用户了解操作的结果,无论是成功还是失败。

总结

​ 通过上述代码片段和详细解释,可以看出聊天功能的实现不仅关注消息的发送和存储,还兼顾了数据验证、安全性和用户体验。这样的设计确保了团队成员之间的实时交流高效且安全,为项目的顺利推进提供了坚实的技术支持。

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 环境准备

  1. 安装微信开发者工具

  2. 注册微信小程序账号

  3. 获取项目代码

    • 克隆项目仓库:

      git clone https://github.com/Whitegveking/102201119-102201102.git//或者下载到自己指定的目录
      
    • 进入项目目录:

      cd 102201119-102201102
      

7.2.2 配置云开发

  1. 登录微信开发者工具

    • 打开微信开发者工具,使用您的微信小程序账号登录。
  2. 导入项目

    • 在微信开发者工具中,选择“导入项目”,选择项目根文件夹。
      导入时请输入自己的小程序id(在注册小程序账号后,如下网页获取小程序id)

  3. 配置云开发

    • 在微信开发者工具中,在编辑器内右键云函数点击第二个上传并部署

    • 初始化云函数和数据库,确保 cloudfunctions 和数据库集合已正确配置。

7.2.3 运行项目

  1. 启动开发环境
    • 在微信开发者工具中,点击上方菜单栏中“工具”的“编译”按钮,启动项目的本地开发环境。
  2. 预览小程序
    • 打开模拟器,即可预览项目。

7.2.4 测试功能

注:
1.微信小程序开发者的系统可能加载缓慢或者未连上网络而出现报错,请耐心等待加载
2.调试前请先到小程序功能中的个人主页更改用户名(在模拟器右边下滑鼠标即可看见切换小程序页面的按纽),确保用户数据存入数据库中

  1. 用户管理
    • 登录小程序,查看和编辑个人资料,确保用户名和其他信息正确显示和保存。
  2. 项目管理
    • 创建新的项目,查看项目列表。
    • 加入已有项目,查看项目详情。
    • 尝试退出和删除项目,确保相关功能正常工作。
  3. 聊天室功能
    • 在项目详情页使用聊天室,发送和接收消息,确保消息实时更新和显示。

7.3 测试人员如何运行你的小程序

​ 测试人员需先克隆仓库,安装必要依赖后,在微信开发者工具中导入项目,确保已登录微信开发者账号。运行项目后,可以通过微信开发者工具的模拟器进行功能测试。(具体间7.2使用说明)


8. 单元测试

在本项目中,单元测试是确保各个功能模块正确性和稳定性的关键步骤。通过系统的测试流程,我们能够及时发现并修复潜在的问题,提升项目的整体质量和用户体验。以下是关于单元测试的详细说明,包括所选用的测试工具、学习过程、测试代码示例以及测试数据构造的思路。


8.1 选用的测试工具及学习过程

选用的测试工具

我们选择了 Mocha 作为单元测试框架,结合 Chai 进行断言。Mocha 是一个功能丰富的 JavaScript 测试框架,适用于 Node.js 和浏览器环境,具有灵活的异步支持和强大的扩展性。Chai 是一个断言库,提供了丰富的断言风格(如 expect, should, assert),使测试代码更具可读性和表达力。

学习单元测试的方法

为了有效地掌握单元测试,我们采取了以下学习步骤:

  1. 官方文档阅读

    通过详细阅读官方文档,了解了基本的使用方法、配置选项以及高级特性。

  2. 在线教程与课程

    • 观看了多个关于 Mocha 和 Chai 的在线教程,学习了如何编写测试用例、组织测试结构以及处理异步代码的测试。
    • 参与了几门在线课程,如 Udemy 的 Mocha & Chai 测试课程,系统学习了单元测试的最佳实践。
  3. 实践与项目应用

    • 在项目中实际应用 Mocha 和 Chai,编写测试用例,逐步积累经验。
    • 通过不断地编写和运行测试,熟悉了测试驱动开发(TDD)的流程和技巧。
  4. 参考开源项目

    • 查阅了多个开源项目中的测试代码,学习了如何在实际项目中组织和编写高质量的测试用例。

通过以上学习方法,我们不仅掌握了 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:用于创建模拟对象和函数,模拟数据库操作,避免实际调用外部依赖。
  • 测试用例

    1. 成功更新状态

      • 输入合法的 projectId 和有效的新状态 "已完成"
      • 模拟数据库返回项目存在且调用者是创建者。
      • 断言函数返回 { success: true }
    2. 无效状态错误

      • 输入合法的 projectId 但无效的新状态 "未知状态"
      • 断言函数返回 { success: false, error: "无效的项目状态" }
    3. 项目不存在错误

      • 输入不存在的 projectId 和有效的新状态。
      • 模拟数据库返回 null,表示项目不存在。
      • 断言函数返回 { success: false, error: "项目不存在" }
    4. 权限不足错误

      • 输入合法的 projectId 和有效的新状态,但调用者不是项目创建者。
      • 模拟数据库返回项目存在但创建者与调用者不同。
      • 断言函数返回 { success: false, error: "您没有权限更改此项目的状态" }

通过这些测试用例,我们覆盖了 updateProjectStatus 云函数的主要逻辑分支,确保其在各种情况下都能正确响应。


8.3 构造测试数据的思路

测试数据构造思路

在构造测试数据时,我们遵循以下原则:

  1. 覆盖所有功能路径

    • 确保测试用例涵盖所有可能的功能路径,包括成功路径和各种失败路径。
    • 例如,在 updateProjectStatus 函数中,我们设计了成功更新、无效状态、项目不存在和权限不足等不同场景的测试用例。
  2. 考虑边界条件和异常情况

    • 测试边界条件,如空输入、极端值和非法输入,确保函数在这些情况下的稳定性。
    • 例如,测试 "未知状态" 是否被正确识别为无效状态。
  3. 模拟真实环境

    • 使用模拟对象和函数(如 Sinon)来模拟真实的数据库操作和用户身份,确保测试的真实性和可靠性。
    • 避免依赖外部环境和实际数据,提升测试的可重复性和独立性。
  4. 防止潜在的安全漏洞

    • 设计测试用例以发现潜在的权限漏洞和安全隐患,确保系统的安全性。
    • 例如,测试非创建者是否能够更改项目状态,防止未授权的操作。
应对测试人员的***难

为了确保测试的全面性和应对未来可能的复杂测试需求,我们在构造测试数据时考虑了以下几点:

  1. 多样化的数据输入

    • 提供多种不同类型和格式的数据输入,确保系统能够处理各种情况。
    • 例如,使用不同长度和内容的项目ID和状态值进行测试。
  2. 模拟不良行为

    • 模拟恶意用户的行为,如尝试注入非法数据或绕过权限验证,确保系统的防护能力。
    • 例如,输入包含特殊字符的状态值,测试系统是否能正确处理。
  3. 自动化测试流程

    • 通过自动化测试脚本,快速执行大量测试用例,提高测试效率和覆盖率。
    • 确保在代码修改后能够及时发现和修复潜在的问题。
  4. 持续集成与持续测试

    • 集成持续集成(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文档和使用说明,便于前端开发和未来的维护工作。

posted on 2024-10-09 15:53  occultator3000  阅读(74)  评论(0编辑  收藏  举报