2024秋软件工程第二次结对作业之程序实现

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/SE2024
这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13281
这个作业的目标
  • 完善改进第一次结对作业的内容
  • 自学新技术,完成程序的实现
  • 与结对队友合作,共同完成web的制作
  • 本人学号 102201308
    本人博客链接 https://www.cnblogs.com/yuyuuu
    队友学号 102201306
    队友博客链接 https://home.cnblogs.com/u/Eeonghan

    KuKu福

  • Github仓库链接:https://github.com/xiaoyu-uu/102201308-102201306
  • 一、具体分工

    102201308何愉心:

  • 搭建页面:我的、觅友、Ku友圈、内容偏好、注册
  • 实时聊天功能的实现
  • 设计模态框和基本的JavaScript框架

    102201306邱雨涵:

  • 搭建页面:首页、团队推荐、登录、项目团队发布
  • 导航栏跳转的实现
  • 页面整体美化与协调

    二、PSP 2.1 个人软件过程表格

    PSP 2.1 阶段 Personal Software Process Stages 预估耗时(小时) 实际耗时(小时)
    Planning 计划 2 1
    Estimate 估计这个任务需要多少时间 120 168
    Development 开发 72 72
    Analysis 需求分析 (包括学习新技术) 24 48
    Design Spec 生成设计文档 8 8
    Design Review 设计复审 2 1
    Coding Standard 代码规范 (为目前的开发制定合适的规范) 1 0.5
    Design 具体设计 24 24
    Coding 具体编码 96 108
    Code Review 代码复审 3 1
    Test 测试(自我测试,修改代码,提交修改) 24 24
    Reporting 报告 12 12
    Test Report 测试报告 6 6
    Size Measurement 计算工作量 0 0
    Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 3 3
    合计 277 308.5

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

    3.1代码实现思路

    • 在协作讨论的过程中,我们交流了各自擅长的技术和感兴趣的方向,确定我们要将原型设计以web的形式呈现
    • 我们在过程中进行合理的分工,因为该项目我们没有以前后端的形式严格分割,所以我们主要以页面分工,各自分别完成几个页面的搭建后再在每个页面加入导航栏、完成页面跳转等
    • 为方便web的运行,我们利用 SM.MS网站进行图片上传,生成图片链接

    3.2关键实现的流程图

    3.3重要代码展示

    3.3.1顶部导航栏

    <header id='header'>
        <div class='center'>
            <h1 class="logo">KuKu福</h1>
            <nav style='overflow:hidden;'>
                <h2 class="none">网站导航</h2>
                <ul class="link">
                    <li class="active"><a href="index.html">首页</a></li>
                    <li><a href="friend.html">觅友</a></li>
                    <li><a href="chat.html">Ku友圈</a></li>
                    <li><a href="mine.html">我的</a></li>
                </ul>
            </nav>
        </div>
    </header>
    
  • 解释:定义了导航栏,包括了首页、觅友、Ku友圈、我的等页面跳转链接。当前页面是“我的”,在用户点击其他导航项时,会跳转到相应的页面。

    3.3.2实时聊天

    模拟WebSocket 发送和接收消息

    const socket = {
        listeners: [],
        send(message) {
            setTimeout(() => this.listeners.forEach(callback => callback(message)), 1000);
        },
        onMessage(callback) {
            this.listeners.push(callback);
        }
    };
    
    
  • 解释:socket 对象有一个 send 方法,用于发送消息。消息发送后通过 setTimeout 模拟服务器延迟回传数据。onMessage 方法用于注册消息监听器,接收到的消息会调用所有注册的回调函数。

    显示消息和更新最新消息

    function displayMessage(message, type) {
        const messageDiv = document.createElement('div');
        messageDiv.className = `chat-message ${type}`;
        messageDiv.textContent = message;
        chatBox.appendChild(messageDiv);
        chatBox.scrollTop = chatBox.scrollHeight; 
    }
    
    function updateLatestMessage(message, time, userName) {
        const chatItems = document.querySelectorAll('.chat-item');
        chatItems.forEach(item => {
            if (item.querySelector('.info div').textContent.includes(userName)) {
                item.querySelector('.latest-message').textContent = message;
                item.querySelector('.timestamp').textContent = time;
            }
        });
    }
    
  • 解释:displayMessage 创建新的消息元素,加入到 chatBox 中,并将聊天框自动滚动到最底部。updateLatestMessage 遍历聊天列表,找到与当前聊天的用户匹配的聊天项,并更新该项的最新消息和时间。

    3.3.3退出团队

    团队列表及删除功能

    <div class="teamcontent">
        <div>
            <div class="groupname">你也喜欢软件工程对不队</div>
            <div class="groupcontent">Project 1</div>
        </div>
        <div>
            <img src="https://s2.loli.net/2024/10/08/n7LHEeDm2M6sbyY.png" onclick="openModal(this)" alt="删除">
        </div>
    </div>
    
  • 解释:展示了团队列表。每个团队项目右侧带有一个删除按钮(通过标签模拟),点击后会调用openModal函数,打开确认删除的模态框。

    模态框确认删除功能

    <!-- Modal -->
    <div id="confirm-modal" class="modal">
        <div class="modal-content">
            <p>确定要退出该团队吗?</p>
            <button class="button" onclick="confirmDelete()">确认</button>
            <button class="button" onclick="closeModal()">取消</button>
        </div>
    </div>
    
  • 解释: 定义了一个模态框,用于确认用户是否要删除某个团队。点击“确认”按钮时,调用confirmDelete函数,删除当前选择的团队元素。

    动态功能的实现(JavaScript)

    function toggleContent(id) {
        const content = document.getElementById(id);
        content.style.display = content.style.display === 'none' ? 'block' : 'none';
    }
    function submitSchedule() {
        const input = document.getElementById('schedule-input').value;
        const displayArea = document.getElementById('schedule-display');
        if (input) {
            displayArea.innerHTML += `<div>${input}</div>`;
            document.getElementById('schedule-input').value = ''; // 清空输入框
        }
    }
    
  • 解释:toggleContent函数用于控制点击时内容区域的显示与隐藏,submitSchedule函数用于提交课表输入内容,并动态添加到页面中。

    四、附加特点设计与展示

    4.1设计创意

    1.兴趣领域偏好:在注册完成后会跳转到内容偏好设置页面,用户可以对自己感兴趣的领域进行偏好选择。
    2.活动推荐:根据用户的兴趣,推荐相关领域的团队,帮助用户更快更准确地接触到志同道合的团队。
    3.团队加入与退出:在进入KuKu福后,用户可以加入其他用户发起的团队,与其一起项目的进行,也可以在“我的”中退出团队,大大提高了合作的便捷性,减少了时间成本。
    4.即时聊天:提供即时聊天功能,允许用户与其他用户活动中实时交流,增强联系的机会。

    4.2实现思想

    功能:

    • 登录与注册
    • 选择领域偏好
    • 加入/退出团队
    • 搜索/添加Ku友
    • 实时聊天
    • 我的个人资料

    4.3部分代码展示

    内容偏好设置

    实时聊天

    4.4实现成果展示

    登录界面

    • 面整体偏绿色系,更具有美观性,让用户在使用的时候更加舒适。
    • 登录界面有注册和忘记密码功能。

    注册界面

    • 注册界面包括基本信息的填写,以及身份的选择,可以通过下拉导航栏选择学生/教师。

    内容偏好设置

    • 内容偏好设置我们小组采用的是拉动条模式,用户在进行选择时可以通过滑动条设置偏好值,系统会根据用户设置推荐团队。

    导航栏跳转

    • 实现了导航栏跳转,且每跳转到一个页面都会加深标签颜色,页面看上去更加美观清晰。

    首页:团队推荐与发布团队

    觅友:搜索/添加好友

    • 如若用户在首页没有找到自己理想的团队,可以在“觅友”页面通过输入目标用户的用户名进行添加,并加入其团队。
    • 下方是通过用户设置的偏好值推荐的其他用户,可以看到他们的姓名、专业、领域等。

    Ku友圈:实时聊天、接收入队/退队消息

    • 实时聊天大大提升了交流的便捷性,节省了时间和空间成本,贴合KuKu福设计的初衷。

    我的:个人信息与设置

    退出团队弹窗

    五、目录说明和使用说明

    测试说明:从Github仓库下载代码压缩包后解压至文件夹,用 VS Code打开该文件夹,下载Live Sever插件,点击选择login.html文件go live!

    测试步骤:按照下述步骤体验感更佳~

    1. 注册与登录

    • 注册:点击左下角的“注册”按钮,填写必要信息(学号、身份、注册手机等),点击注册。
    • 登录:注册后的用户可输入信息,通过“登录”按钮访问个人账户。

    2. 兴趣偏好设置

    • 登录后,可以对自身感兴趣的领域进行偏好值设置

    3. 浏览

    • 在“首页”页面,浏览推荐的团队,也可以发布团队。

    4. 添加其他Ku友

    • 访问“觅友”页面,浏览和添加感兴趣的Ku友,参与讨论和活动,结识新朋友。

    5. 实时聊天

    • 访问“Ku友圈”页面,与其他用户进行即时聊天,分享兴趣和想法。增强互动。
    • Ku邮箱可用来接受团队的入队/退队通知

    8. 我的个人资料

    • 访问“我的”页面,可以设置个人信息
    • 可以在“我的团队”中,点击右边的按钮进行退队操作

    六、单元测试

    6.1 测试工具说明和简要教程

    a.测试工具

  • 我们选用了 Jest 作为测试框架,这是一个非常流行的JavaScript测试框架

    b.学习方法:

  • 理解单元测试的目的:
  • 单元测试是用来验证代码的最小可测试单元(通常是函数或方法)是否按预期工作。

  • 学习基本概念:
  • 了解测试断言、测试用例、测试套件、测试框架等概念。

  • 选择合适的测试框架:
  • 根据使用的编程语言和项目需求选择合适的测试框架。

  • 编写测试用例:
  • 学习如何编写测试用例,包括设置测试环境、执行测试代码和验证结果。

  • 使用模拟和存根:
  • 学习如何使用模拟(mocks)和存根(stubs)来隔离测试单元。

  • 实践:
  • 通过实际编写和运行测试来提高相应技能。

    c.Jest 测试简易教程

    1. 安装 Jest

    在项目中安装 Jest:

    npm install --save-dev jest
    

    2.配置package.json

    在 package.json 中添加以下测试脚本,以便通过命令运行测试:

    {
      "scripts": {
        "test": "jest"
      }
    }
    

    3.编写测试代码

    首先,编写要测试的函数,如下:

    // sum.js
    function sum(a, b) {
      return a + b;
    }
    module.exports = sum;
    
    

    然后编写对应的测试文件:

    // sum.test.js
    const sum = require('./sum');
    
    test('adds 1 + 2 to equal 3', () => {
      expect(sum(1, 2)).toBe(3);
    });
    
    

    4.运行测试

    使用以下命令运行测试:

    npm test
    

    如果测试通过,你将看到如下输出:

    PASS  ./sum.test.js
    ✓ adds 1 + 2 to equal 3 (5 ms)
    

    6.2项目部分单元测试代码及函数说明

    1.Confirm Delete

    代码:

    describe('Confirm Delete', () => {
      test('should remove currentElement from DOM', () => {
        document.body.innerHTML = `
          <div class="test-element">Test Element</div>
        `;
        const element = document.querySelector('.test-element');
        script.currentElement = element;
        script.confirmDelete();
        expect(document.querySelector('.test-element')).toBeNull();
      });
    });
    

    测试函数: confirmDelete()

  • 目的: 测试确认删除元素的功能。
  • 操作: 设置一个测试元素。将currentElement设置为该测试元素,然后调用confirmDelete函数,检查该元素是否从DOM中被移除。

    2.Toggle Content

    代码:

    describe('Toggle Content', () => {
      test('should toggle the display of content', () => {
        document.body.innerHTML = `
          <div id="test-content" style="display: none;">Hidden Content</div>
        `;
        const content = document.getElementById('test-content');
        script.toggleContent('test-content');
        expect(content.style.display).toBe('block');
        script.toggleContent('test-content');
        expect(content.style.display).toBe('none');
      });
    });
    

    测试函数:toggleContent(id)

  • 目的: 测试内容的显示和隐藏切换功能。
  • 操作: 首先设置一个初始为隐藏(display: none)的内容元素。调用toggleContent函数后,检查元素的display属性是否变为block(显示)。再次调用toggleContent函数,检查display属性是否变回none(隐藏)。

    6.3 构造测试数据的思路

  • 正常情况:
  • 测试正常、预期内的输入,比如toggleContent测试中,检查隐藏内容是否能够被正确显示。

  • 边界情况:
  • 测试输入的边界值,例如数组的空值、最小值和最大值。

  • 异常情况:
  • 测试非预期的输入,比如null、undefined、错误格式的数据等,以确保函数能够妥善处理。

  • 依赖模拟:
  • 对于依赖外部资源的函数,使用模拟对象来代替实际依赖,比如在openModal测试中模拟DOM元素。

  • 逆向思维:
  • 考虑测试人员可能会如何尝试破坏代码,比如通过confirmDelete测试检查是否能够正确删除元素。

  • 性能考虑:
  • 在实际测试中,可以考虑构造大量数据来测试性能。

  • 预见挑战:
  • 思考测试人员可能会如何为难,比如通过构造不符合预期的输入来测试函数的错误处理能力

    七、Github代码嵌入记录截图

    八、遇到的代码模块异常及解决方法

    1.样式不生效

  • 问题:再写一个网页的时候往往需要很多的元素搭建起来,在团队协作的时候如果没有制定统一的风格,选择器等很容易发生冲突,从而导致CSS样式没有应用到元素上
  • 解决方法:
    1.检查CSS选择器是否正确,确保样式文件被正确加载
    2.及时补救,确定编写代码风格
  • 所做尝试:修改class名等
  • 收获:在进行协作编程的时候一定要注意事先确定好基本的编程风格,以免导致事后的返工

    2.资源加载失败

  • 问题:图片、样式表或脚本文件加载失败
  • 所做尝试:检查资源的路径等
  • 解决方法:将图片资源上传SM.MS网站,检查资源的URL是否正确,确保资源文件已正确上传到服务器

    3.事件处理错误

  • 问题:事件监听器未正确绑定或触发
  • 解决方法:
    1.查询资料学习
    2.确保事件监听器正确绑定到目标元素,并且事件处理函数正确定义
  • 收获:对该功能的原理更加清楚,应用更为熟练

    九、队友互评

  • 值得学习的地方:情绪稳定,善于查阅资料和利用网络资源,对css掌握熟练,完成任务效率高,不拖沓。
  • 需要改进的地方:还需利用好碎片时间。
  • posted @ 2024-10-10 21:02  -myimagination  阅读(47)  评论(0编辑  收藏  举报