软件工程结对作业(第二次之程序实现)

这个作业属于哪个课程 首页 - 软件工程2024 - 福州大学 - 班级博客 - 博客园
这个作业要求在哪里 2024秋软件工程结对作业(第二次之程序实现)
这个作业的目标 站在程序员的角度,给出这个产品的核心模块的编码的原型
学号 102202130、042201401
github项目地址1 linye2005/042201401-102202130 (github.com)
github项目地址2 786260029/042201401-102202130 (github.com)

第二次结对作业-程序实现

一、具体分工

学号 分工
102202130 前端开发和用户界面设计、部分功能实现、博客
042201401 前端开发和用户界面设计、部分功能实现、README.md文件

二、PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 120 120
·Estimate 估计这个任务需要多少时间 120 120
Development 开发 3860 3960
·Analysis 需求分析 (包括学习新技术) 630 700
·Design Spec 生成设计文档 180 180
·Design Review 设计复审 120 120
·Coding Standard 代码规范 (为目前的开发制定合适的规范) 60 90
·Design 具体设计 320 330
·Coding 具体编码 2000 2040
·Code Review 代码复审 150 150
·Test 测试(自我测试,修改代码,提交修改) 400 350
Reporting 报告 760 710
·Test Repor 测试报告 240 250
·Size Measurement 计算工作量 120 100
·Postmortem&Process Improvement Plan 事后总结, 并提出过程改进计划 400 360
合计 4740 4790

三、解题思路描述与设计实现说明

3.1代码实现思路与文字描述

概述: 我们的项目“ProjectPartner”旨在创建一个平台,让用户能够发布项目、招募合作伙伴,并进行实时交流。实现这个目标涉及到前端页面展示、用户输入验证、后端逻辑处理以及数据库交互。

用户输入验证:在前端使用JavaScript进行初步验证,确保用户输入符合要求(如邮箱格式、所有信息都填写)。

数据库交互:使用MySQL来存储用户信息、项目信息和聊天记录。

交流实现:使用WebSocket实现聊天功能。

基础功能:创建项目(完成创建后可以在管理项目的我创建的项目中查看)、加入项目(点击加入按钮后可以在管理项目的我加入的项目中查看)、聊天(聊天记录可以永久保存)。

附加功能:我的信息管理、首页欢迎与资讯、导航栏跳转、弹窗提示、注销账户。

为了符合大家的习惯,我们的消息页面左侧为用户栏,右侧为聊天窗口,右下方为输入栏。

3.2关键实现的流程图或数据流图

graph TD A[用户界面] -->|用户操作| B[首页] A -->|用户操作| C[我的] A -->|用户操作| D[项目] A -->|用户操作| E[消息] A -->|用户操作| F[注册] A -->|用户操作| G[登录] A -->|用户操作| H[退出登录] B --> I[查看项目信息] D -->|创建| J[发起项目] D -->|管理| K[管理项目] D -->|修改| L[修改项目信息] D -->|删除| M[删除项目] D -->|加入| N[加入项目] D -->|退出| O[退出项目] C -->|查看| P[我的信息] C -->|编辑| Q[修改信息] E --> R[实时通讯系统] F --> S[注册服务] G --> T[登录服务] H --> U[注销服务] I --> V[项目数据库] J --> V K --> V L --> V M --> V N --> V O --> V P --> W[用户数据库] Q --> W S --> W T --> W U --> W V -->|数据返回| A W -->|数据返回| A R -->|消息返回| A

项目管理UML图:

classDiagram class Project { +String name +String startDate +String recruitPeople +String direction +String tags +String description +Number id } class ProjectManagement { +Project[] createdProjects +Project[] joinedProjects +void updateProjectManagement() +void deleteProject(String projectId) +void applyJoinProject(String projectId) +void leaveProject(String projectId) +void editProject(String projectId) } class UserInterface { +void displayProjects() +void showProjectForm() +void handleProjectCreation() +void handleProjectDeletion() +void handleProjectJoining() +void handleProjectLeaving() +void handleProjectEditing() } class LocalStorage { +String createdProjects +String joinedProjects +String getProjects(String key) +void setProjects(String key, String value) } ProjectManagement --> Project : manages UserInterface --> ProjectManagement : interacts UserInterface --> LocalStorage : uses ProjectManagement --> LocalStorage : accesses

说明

  • Project: 表示单个项目,包含项目的名称、开始日期、招募人数、方向、标签、描述和ID。
  • ProjectManagement: 负责管理项目,包括创建、删除、加入、退出和编辑项目。
  • UserInterface: 表示用户界面,负责显示项目、显示项目表单、处理项目创建、删除、加入、退出和编辑。
  • LocalStorage: 表示本地存储,用于存储和检索项目数据

项目管理系统结构图:

graph TD A[项目管理系统] --> B[项目信息] A --> C[用户信息] A --> D[用户操作] A --> E[项目数据库] B --> F[创建项目] B --> G[编辑项目] B --> H[删除项目] C --> I[加入项目] C --> J[退出项目] D --> K[操作反馈] F --> E G --> E H --> E I --> E J --> E K --> E

图解说明

  • 项目管理系统: 顶层节点,表示整个系统。
  • 项目信息: 包括创建、编辑和删除项目的操作。
  • 用户信息: 表示系统中的用户数据。
  • 用户操作: 包括用户对项目的加入和退出操作。
  • 项目数据库: 存储所有项目和用户信息的数据库。
  • 创建项目: 用户可以创建新项目。
  • 编辑项目: 用户可以编辑已存在的项目。
  • 删除项目: 用户可以删除项目。
  • 加入项目: 用户可以加入已有的项目。
  • 退出项目: 用户可以退出项目。
  • 操作反馈: 系统对用户操作的反馈。

3.3重要的/有价值的代码片段及解释

代码片段 1: 表单字段更新逻辑

function updateFormFields() {
  var identity = document.getElementById('identitySelect').value;
  var studentNumberDiv = document.getElementById('studentNumberDiv');
  var teacherNumberDiv = document.getElementById('teacherNumberDiv');
  var majorDiv = document.getElementById('majorDiv');
  var researchDiv = document.getElementById('researchDiv');
  if (identity === 'student') {
    studentNumberDiv.classList.remove('hidden');
    teacherNumberDiv.classList.add('hidden');
    majorDiv.classList.remove('hidden');
    researchDiv.classList.add('hidden');
  } else if (identity === 'teacher') {
    studentNumberDiv.classList.add('hidden');
    teacherNumberDiv.classList.remove('hidden');
    majorDiv.classList.add('hidden');
    researchDiv.classList.remove('hidden');
  }
}

解释:

  • 此函数 updateFormFields 根据用户选择的身份(学生或教师)动态显示或隐藏特定的表单字段。
  • 使用 document.getElementById 获取相应的 DOM 元素。
  • 使用 classList.addclassList.remove 方法来控制元素的显示和隐藏。
  • 如果身份是学生,则显示学生学号和专业相关的字段,隐藏教师相关的字段。
  • 如果身份是教师,则显示教师工号和研究方向相关的字段,隐藏学生相关的字段。

代码片段 2: 表单提交逻辑

document.getElementById('registrationForm').addEventListener('submit', function(event) {
  event.preventDefault(); // 阻止表单默认提交行为

  var identity = document.getElementById('identitySelect').value;
  var studentNumber = document.getElementById('studentNumberDiv').getElementsByTagName('input')[0].value.trim();
  var teacherNumber = document.getElementById('teacherNumberDiv').getElementsByTagName('input')[0].value.trim();

  if ((identity === 'student' && studentNumber !== '') || (identity === 'teacher' && teacherNumber !== '')) {
    // 如果用户填写了对应身份的信息,则跳转到登录页面
    window.location.href = '登录.html';
  } else {
    alert('请填写完整您的信息。');
  }
});

解释:

  • 此段代码为注册表单添加了 submit 事件监听器。
  • 使用 event.preventDefault() 阻止表单的默认提交行为,允许通过JavaScript进行进一步处理。
  • 获取用户选择的身份以及学生学号或教师工号的输入值。
  • 使用 trim() 方法去除输入值两端的空白字符。
  • 根据用户选择的身份验证相应字段是否已填写。
  • 如果验证通过,使用 window.location.href 跳转到登录页面。
  • 如果验证失败,使用 alert 弹出提示信息,提醒用户填写完整信息。

代码片段3: 聊天窗口控制逻辑

document.querySelectorAll('.chat-item').forEach(item => {
    item.addEventListener('click', function() {
        // 隐藏所有聊天窗口
        document.querySelectorAll('.chat-window').forEach(win => {
            win.style.display = 'none';
        });
        // 移除所有聊天项的激活状态
        document.querySelectorAll('.chat-item').forEach(item => {
            item.classList.remove('active');
        });
        // 显示被点击的聊天窗口并添加激活状态
        const target = this.getAttribute('data-target');
        const chatWindow = document.getElementById(target);
        chatWindow.style.display = 'flex';
        this.classList.add('active');
    });
});

解释:此代码片段用于控制聊天应用中的聊天窗口切换逻辑。使用 document.querySelectorAll 获取所有的聊天项(.chat-item),并对每一个聊天项添加点击事件监听器。在点击事件中,首先遍历并隐藏所有的聊天窗口(.chat-window),确保在切换聊天窗口时,其他聊天窗口是隐藏状态。接着,遍历并移除所有聊天项的激活状态(.active),以确保只有当前被点击的聊天项处于激活状态。通过 this.getAttribute('data-target') 获取被点击聊天项关联的聊天窗口的ID。使用 document.getElementById 根据ID获取对应的聊天窗口元素,并将其设置为显示状态(flex)。最后,给被点击的聊天项添加激活状态的样式(.active)。

关键点:封装性 、用户交互性能考虑可维护性扩展性(添加新的聊天窗口,只需添加相应的 .chat-item.chat-window 元素)

代码片段4: 创建项目

document.getElementById('project-form').addEventListener('submit', function(event) {
    event.preventDefault();
    const project_name = document.getElementById('project-name').value;
    const start_date = document.getElementById('start-date').value;
    const recruit_people = document.getElementById('recruit-people').value;
    const project_direction = document.getElementById('project-direction').value;
    const add_tags = document.getElementById('add-tags').value;
    const project_description = document.getElementById('project-description').value;

    const newProject = {
        name: project_name,
        startDate: start_date,
        recruitPeople: recruit_people,
        direction: project_direction,
        tags: add_tags,
        description: project_description,
        id: Date.now()
    };

    let createdProjects = JSON.parse(localStorage.getItem('createdProjects')) || [];
    createdProjects.push(newProject);
    localStorage.setItem('createdProjects', JSON.stringify(createdProjects));
    updateProjectManagement();
    document.getElementById('create-project').style.display = 'none';
});

解释:这段代码监听创建项目表单的提交事件。它获取表单中的输入数据,创建一个新的项目对象,并将其添加到本地存储中的项目数组。然后更新项目管理界面。

代码片段5: 动态生成项目卡片

function generateProjectCards(sectionId) {
    if (sectionId === 'join-project') {
        const container = document.querySelector('#join-project .cards-container');
        container.innerHTML = '';
        const projects = [
            /* 省略部分项目信息*/
        ];

        projects.forEach(project => {
            const card = document.createElement('div');
            card.className = 'project-card';
            card.innerHTML = `
                <h3>${project.title}</h3>
                <p>创建人:${project.creator}</p>
                <p>${project.description}</p>
                <button onclick="applyJoinProject('${project.id}')">申请加入</button>
            `;
            container.appendChild(card);
        });
    }
}

解释:这个函数用于动态生成项目卡片。当用户点击侧边栏的“加入项目”链接时,它会清空现有的项目卡片并生成新的项目卡片。

四、附加特点设计与展示

4.1 导航栏(附加功能)

意义:导航栏是用户与网站交互的桥梁,它不仅提供了页面内各个部分的快速访问,还增强了用户体验。在“ProjectPartner”平台中,导航栏的附加功能可以包括动态高亮当前激活的链接、搜索框集成以及用户个人中心的快速访问,这些功能有助于用户更高效地找到所需信息。

实现思路:

  1. 动态高亮:使用JavaScript监听导航项的点击事件,并动态添加激活状态的样式。
  2. 用户个人中心:提供一个快速链接到用户个人中心,方便用户管理个人信息和参与的项目。

重要的/有价值的代码片段,并解释:

/* 导航栏样式 */
header {
    background-color: #f8f9fa;
    padding: 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

/* 导航项目样式 */
nav ul {
    list-style-type: none;
    margin: 0;
    padding: 0;
    display: flex;
}

nav ul li a {
    text-decoration: none;
    color: #333;
}

nav ul li a:hover {
    text-decoration: underline;
}

nav ul li a.active {
    font-weight: bold;
    color: #000;
}

这段CSS代码定义了导航栏的基本样式。header类设置了导航栏的背景颜色、内边距,并使用Flexbox布局确保内容水平和垂直居中。nav ul类去除了列表的默认样式,并使用Flexbox布局导航链接。nav ul li a类定义了链接的默认样式,包括无文本装饰、颜色等。nav ul li a:hover类为鼠标悬停状态添加了下划线文本装饰,而nav ul li a.active类则定义了激活状态的样式,包括字体加粗和颜色变化。

// 为侧边栏链接添加点击事件监听器
document.querySelectorAll('.sidebar ul li a').forEach(item => {
    item.addEventListener('click', function(event) {
        event.preventDefault(); // 阻止链接默认行为

        const targetSection = this.getAttribute('href').substring(1);
        const sections = document.querySelectorAll('.project-content > div');

        // 隐藏所有内容部分
        sections.forEach(section => {
            section.style.display = 'none';
        });

        // 移除所有侧边栏链接的激活状态
        document.querySelectorAll('.sidebar ul li a').forEach(link => {
            link.classList.remove('active');
        });

        // 激活当前链接
        this.classList.add('active');

        // 显示对应的内容部分
        document.getElementById(targetSection).style.display = 'block';
    });
});

这段JavaScript代码为导航栏中的链接添加了点击事件监听器。当用户点击某个链接时,它会阻止默认的跳转行为,隐藏所有内容部分,移除其他链接的激活状态,并将当前点击的链接设置为激活状态,最后显示对应的内容部分。

成果展示:

4.2 首页(附加功能)

意义:首页是用户访问“ProjectPartner”平台时首先看到的页面,它不仅需要展示平台的核心价值和服务,还应该包含一些附加功能来提升用户体验和互动性。

实现思路:在首页集成一个资讯推送区域,实时展示最新的行业动态,以吸引用户进一步探索和参与。

重要的/有价值的代码片段,并解释:

<!-- 首页动态资讯推送区域 -->
<section class="news-feed">
  <div class="news-item" onclick="location.href='#'">最新项目更新:云计算平台升级</div>
  <div class="news-item" onclick="location.href='#'">行业动态:生物能源新突破</div>
  <div class="news-item" onclick="location.href='#'">深度学习实验室新成果发布</div>
</section>

这展示了如何在首页集成资讯推送区域。<section>标签用于定义页面的不同部分,<div>用于创建资讯项和项目更新项。

成果展示:

4.3弹窗设置(附加功能)

意义: 弹窗是一种有效的用户交互方式,它可以用于各种场景,如提示信息、表单提交确认、广告展示等。在“ProjectPartner”平台中,弹窗可以用于申请加入项目时的确认提示,确保用户在提交申请前有机会再次确认自己的选择,从而提高用户体验和操作的准确性。

实现思路:

  1. 使用HTML和CSS创建弹窗结构:定义弹窗的HTML结构和样式,确保弹窗在视觉上与网站整体风格一致。
  2. 使用JavaScript控制弹窗显示和隐藏:通过监听用户的操作(如点击按钮)来控制弹窗的显示和隐藏。
  3. 弹窗内容动态加载:根据用户的操作动态加载弹窗内容,如显示用户即将加入的项目信息。

重要的/有价值的代码片段,并解释:

// 获取弹窗元素和关闭按钮
var modal = document.getElementById("myModal");
var span = document.getElementsByClassName("close")[0];

// 点击按钮打开弹窗
function openModal() {
  modal.style.display = "block";
}

// 点击<span> (x) 关闭弹窗
span.onclick = function() {
  modal.style.display = "none";
}

window.onclick = function(event) {
  if (event.target == modal) {
    modal.style.display = "none";
  }
}

这段JavaScript代码控制弹窗的显示和隐藏。openModal函数设置弹窗的显示,span.onclickwindow.onclick函数设置点击关闭按钮和点击窗口之外区域时隐藏弹窗。

成果展示:

  • 确认操作:用户在申请加入项目前,会弹出确认提示,确保用户明确自己的操作。
  • 提升用户体验:通过弹窗提示,用户可以更清楚地了解自己的操作结果,减少误操作。
  • 视觉一致性:弹窗的样式与网站整体风格一致,提升了整体的美观度。

通过这种弹窗设置,可以有效地提高用户的操作准确性和满意度,同时也增强了平台的交互性和专业性。

4.4成果展示

当前功能
  • 登录界面针对“学工号”实施了限制,仅允许输入数字字符。

  • 首页精心设计了项目推荐功能,根据用户偏好及历史行为,智能推荐几个合适的项目,助力用户快速发现心仪之选。

  • 注册界面可选择身份,填写不同注册信息。针对“邮箱”,“电话”实施限制,要求必须填完所有注册信息方可注册。

  • 导航栏可跳转至首页,消息,项目和我的页面,实现随心跳转,方便实现页面切换

  • 消息界面功能全面,支持消息的发送及历史记录的保存,便于用户随时回顾交流内容

  • 项目界面内容丰富,涵盖了项目的创建、加入及管理三大板块。其中,管理项目细分为“我加入的项目”与“我创建的项目”两大类别,所有相关操作在用户未注销账户前均持续有效。

    • 在创建项目时,用户需填写项目名称、选择开始日期(通过日历便捷选取)、设定招募人数、明确项目方向、添加相关标签,并编辑正文内容。点击“创建项目”按钮后,所填信息将即时展示在项目管理界面中。

    • 加入项目流程中,用户只需点击感兴趣项目下的“申请加入”按钮,系统会弹出确认弹窗,这一人性化设计旨在促使用户做出慎重选择。确认后,该项目将自动归入“项目管理”下的“我加入的项目”列表中,同时原“申请加入”按钮文字变更为“已加入”,清晰反映项目状态。

    • 在“我加入的项目”管理下,每个项目均设有“退出”按钮,用户点击后,该项目内容将被删除,实现灵活管理

    • 对于“我创建的项目”,每个项目均配备删除与修改按钮。点击删除按钮,项目将从“我创建的项目”列表中移除;点击修改按钮,则跳转至创建项目页面,并预填充原项目信息,便于用户快速修改后更新项目信息

  • 我的界面允许用户填写并保存个人信息,这些信息在用户未注销账户前将长期保留,便于用户随时查看与更新。

  • 每个界面增加背景图,增加美观

未来功能
  • 表单验证:为注册和登录页面增加表单验证功能,确保用户输入合法的内容。
  • 动态内容加载:实现通过JavaScript动态加载项目数据,而不是仅使用静态HTML。
  • 更多功能敬请期待!

五、目录说明和使用说明

5.1目录结构及说明

ProjectPartner/
│
├── pictures/              # 存放图片资源
│   ├── banner.jpg
│   ├── IMG_1921.JPG
│   ├── ...
│   └── IMG_1960J
│
├──注册.html # 存放HTML页面文件
│
├──登录.html
│
├──首页.html
│
├──消息.html
│
├──我的.html
│
├──项目.html
├──项目.css
├──项目.js
│
└── README.md            # 项目说明文件

说明:

  • 有一个项目.css文件,它包含项目页面的样式定义。
  • 项目.js文件包含用于项目页面交互的脚本。
  • 项目的所有HTML页面文件。每个文件代表应用程序的一个页面,如登录.html首页.html我的.html项目.html
  • pictures/: 这个文件夹包含项目中使用的所有图片资源。
  • README.md: 这是一个文本文件,通常包含项目的描述、安装指南、使用说明等。

5.2测试人员运行网页步骤

  1. 准备环境
    • 确保你的计算机上安装了现代浏览器,如Google Chrome、Mozilla Firefox、Microsoft Edge等。
  2. 打开HTML文件
    • 双击任何一个HTML文件(如登录.html),这将使用默认的网页浏览器打开该文件。
  3. 在浏览器中查看
    • 浏览器将加载并显示网页内容。
  4. 页面跳转
    • 在打开的网页中,通常会有一些链接或按钮允许你跳转到其他页面(如从首页.html跳转到消息.html我的.html)。
    • 点击这些链接或按钮,即可实现页面之间的跳转。
  5. 调试和测试
    • 如果需要对网页进行调试,可以右键点击页面元素,选择“检查”(Inspect),打开开发者工具进行调试。
    • 测试人员可以检查页面的响应性、功能实现、链接是否正确等。

六、单元测试

6.1测试工具选择及单元测试简易教程

何为单元测试:对软件中的最小可测试单元进行检查和验证,“单元”可以是一个函数、方法、类、功能模块或者子系统。可以有效地测试某个程序模块的行为,是未来重构代码的信心保证。测试用例要覆盖常用的输入组合、边界条件和异常。单元测试代码要非常简单,如果测试代码太复杂,那么测试代码本身就可能有bug。单元测试通过了并不意味着程序就没有bug了,但是不通过程序肯定有bug。

选用的测试工具: Jest

学习单元测试: 通过在线教程、官方文档、技术博客和实践项目来学习单元测试。Jest 是一个由Facebook开发的JavaScript测试框架,它非常适合用于前端项目的单元测试。

简易教程:

  1. 安装 Jest: 在你的项目中安装Jest。

    bash

    npm install --save-dev jest
    
  2. 配置 Jest:package.json 文件中添加测试脚本。

    json

    "scripts": {
      "test": "jest"
    }
    
  3. 编写测试用例: 创建一个测试文件,例如 6.2代码

  4. 运行测试: 在命令行中运行 npm test 来执行测试。

6.2部分单元测试代码及说明

用户注册功能

说明:register 测试正常用户注册后能否成功注册。(测试用例1

import { register } from './UserService';

describe('UserService', () => {
  it('should register a user successfully', () => {
    const user = { username: 'testuser', email: 'test@example.com', password: 'password123' };
    const result = register(user);
    expect(result.success).toBe(true);
  });
});

输入不符合要求的邮箱格式,验证是否阻止注册并返回错误。(测试用例2

注册信息没有填完,验证是否阻止注册。(测试用例3

用户登录功能—login测试登录界面学工号和密码是否符合要求,若不符合要求,验证是否阻止登录并返回错误。(测试用例4

import { login } from './UserService';

describe('UserService', () => {
  it('should not allow login with invalid credentials', () => {
    const credentials = { username: 'wronguser', password: 'wrongpassword' };
    const result = login(credentials);
    expect(result.success).toBe(false);
    expect(result.message).toContain('Invalid credentials');
  });
});

用户退出功能

验证用户退出后,是否能够返回到登录界面。(测试用例5

import { logout } from './UserService';

describe('UserService', () => {
  it('should logout user and redirect to login screen', () => {
    const result = logout();
    expect(result.success).toBe(true);
    expect(result.message).toBe('User logged out successfully');
  });
});

聊天功能—说明:sendMessage函数测试聊天功能,消息点击发送,验证是否有消息出现到聊天窗口。(测试用例6

import { sendMessage } from './ChatService';

describe('ChatService', () => {
  it('should display message in chat window after sending', () => {
    const message = 'Hello, World!';
    const result = sendMessage(message);
    expect(result.success).toBe(true);
    expect(result.message).toBe(message);
  });
});

项目发布功能—发布项目时项目标题为空,验证是否阻止发布并返回错误。(测试用例7

说明: navigate函数测试点击导航栏的不同组件,验证是否会实现跳转。(测试用例8)

import { navigate } from './NavigationService';

describe('NavigationService', () => {
  it('should navigate to different components on clicking navigation bar', () => {
    const result = navigate('Home');
    expect(result.success).toBe(true);
    expect(result.component).toBe('Home');
  });
});

消息中选择不同的人聊天,验证聊天窗口内信息是否不同。(测试用例9

正常创建项目—正常创建项目,验证项目是否成功发布。(测试用例10

6.构造思路与测试人员的***难

构造测试数据的思路:

  1. 边界值分析: 选择边界值作为测试数据,例如空字符串、特殊字符、极端值等。
  2. 等价类划分: 将输入数据分为有效等价类和无效等价类,确保每个类别都有测试用例。
  3. 错误推测法: 基于经验和直觉推测可能的错误,并构造相应的测试数据。
  4. 测试用例优先级: 优先测试核心功能和最可能出错的部分。

考虑测试人员的***难:

  1. 覆盖所有分支: 确保测试用例覆盖所有的代码分支,包括正常流程和异常流程。
  2. 使用 Mock 和 Spy: 对外部依赖进行模拟和监控,确保测试的独立性和可控性。
  3. 随机化测试数据: 使用随机化方法生成测试数据,以增加测试的不确定性和覆盖面。
  4. 持续集成: 将单元测试集成到持续集成流程中,确保每次代码提交都会自动运行测试。

七、Github签入截图



八、困难及解决方法

困难一:代码环境的选取

  • 困难描述:在项目开发初期,面对众多的代码编辑器和开发环境选择,难以决定哪种工具最适合团队的开发需求和工作流程。
  • 解决尝试:通过询问学长学姐和同学,对比不同编辑器的功能特性,如插件支持、代码提示、调试工具等。尽量使用我们电脑上现有软件。
  • 是否解决:是
  • 有何收获:提升了基于信息收集和分析做出决策的能力。意识到选择正确的开发环境对提升开发效率的重要性。学会了如何快速适应新工具,为未来可能的工具更换或技术更新做好准备。

困难二:页面刷新导致数据丢失

  • 困难描述:在创建项目后,先前创建的项目记录会丢失。

  • 解决尝试:使用浏览器的本地存储:尝试使用localStoragesessionStorage来保存数据,但发现这些方法只适用于小量数据且不便于管理。

    服务器端数据库存储:考虑将数据保存在服务器端的数据库中,这样即使页面刷新,数据也能从数据库中重新加载。

    前端状态管理:使用前端状态管理库(如Redux)来管理状态,但发现对于本项目来说过于复杂。

  • 是否解决:是

  • 有何收获:学会了在Node.js环境下使用MongoDB进行数据的增删改查操作。加深了对前后端分离架构的理解,明确了前端发送请求和后端处理请求的流程。加深了API的理解,学会了如何开发用于处理增删改查的API。

困难三:消息聊天记录未持久化

  • 困难描述:聊天应用中,用户发送的消息在页面刷新后丢失,无法持久化保存聊天记录。

  • 解决尝试:使用浏览器的本地存储:尝试使用localStoragesessionStorage来保存数据,但发现这些方法只适用于小量数据且不便于管理。

    服务器端数据库存储:考虑将数据保存在服务器端的数据库中,这样即使页面刷新,数据也能从数据库中重新加载。

    前端状态管理:使用前端状态管理库(如Redux)来管理状态,但发现对于本项目来说过于复杂。

  • 是否解决:是

  • 有何收获:学习了如何设计适合存储聊天记录的数据库模型。要多查阅资料,尝试各种方法。

困难四:后台环境配置困难

  • 困难描述:在配置Node.js项目的后台环境时,遇到了依赖安装失败、数据库连接错误等问题。

  • 解决尝试:依赖版本检查:确保所有依赖库的版本兼容。使用npm--legacy-peer-deps选项:解决依赖库之间的兼容性问题。

  • 是否解决:是

  • 有何收获:学会了如何使用npm管理项目依赖,解决依赖冲突问题。掌握了使用dotenv库来管理环境变量的方法。:加深了对MongoDB数据库连接和配置的理解

九、评价你的队友

102202130林烨对042201401陈高菲的评价:陈高菲同学的动手实践能力和学习新技术的速度较强,经常我在犹犹豫豫不知道怎么下手寻找切入点的时候,她总是能很快地找到相应的解决方案并且实现它。我欣赏陈高菲同学出色的动手实践能力,她的敢想敢做的行事风格总是能有效推动我们的项目进度,期待未来能够有再次与他合作的机会。(值得学习的地方)她总体上做得很好,但在一些细节处理上还有提升空间,更加关注细节将有助于提高工作质量。(需要改进的地方)

042201401陈高菲对102202130林烨的评价:林烨同学在项目中展现出极高的逻辑思维能力和扎实的基础知识,总能帮我解决我死磕很久的问题。同时,她的耐心与细致也给我留下了深刻印象,在我遇到困惑时,他总能耐心指导并帮助我理清思路。她的思维敏捷,总是会考虑到一些我没有考虑到的问题。与林烨的合作让我看到了自己需要提升的地方。(值得学习的地方)在面对紧张的项目进度时,她有时会显得有些焦虑,可以进一步提高自己的压力管理能力,以更好地应对工作中的挑战。(需要改进的地方)

posted @ 2024-10-10 20:53  Valerie2077  阅读(8)  评论(0编辑  收藏  举报