软件工程第二次结对作业
这个作业属于哪个课程 | https://edu.cnblogs.com/campus/fzu/SE2024 |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzu/SE2024/homework/13281 |
这个作业的目标 | 学习和使用框架模型,完成项目协作app的开发 |
学号 | 102201137 |
结对成员学号 | 102201137 102201237 |
程序结果的演示图:
我们新建了一个账号为1022012372的账号,演示了发布项目,和相互进行聊天,和进行了修改密码的测试,演示视频链接如下所示
https://www.bilibili.com/video/BV1jd1yYVE8C/?share_source=copy_web&vd_source=e8bb1b7d118f4e2b262da67871345c95
目录
- 1.Github的仓库地址
- 2.具体分工
- 3.psp表格
- 4.解题思路及代码实现说明
- 5.附加特点的设计与展示
- 6.目录说明和结构说明
- 7.单元测试
- 8.Github的代码签入记录
- 9.遇到的代码模块异常或结对困难及解决方法
- 10.评价一下队友
1.Github的仓库地址
https://github.com/12190-bit/102201137-102201237/tree/master?tab=readme-ov-file
2.具体分工
102201137负责完成app模型的构建
102201237负责对app进行测试
3.psp表格
PSP阶段 | 预估耗时(小时) | 实际耗时(小时) |
---|---|---|
计划 | 2 | 2 |
开发 | 10 | 13 |
需求分析 | 3 | 3 |
设计文档 | 3 | 3 |
设计复审 | 5 | 6 |
代码规范 | 15 | 18 |
具体设计 | 15 | 16 |
具体编码 | 15 | 19 |
代码复审 | 5 | 6 |
测试 | 5 | 6 |
报告 | 5 | 6 |
测试报告 | 5 | 5 |
计算工作量 | 6 | 7 |
事后总结及过程改进计划 | 5 | 8 |
合计 | 99 | 118 |
4.解题思路及代码实现说明
4.1.总体的实现思路
1.先在若依框架的前端页面增加所需要的键值,以及所需要的数据库的表(如下图所示)
2.增加专业管理所需要的专业
3.建表后后台管理进行对用户的管理删除修改等待,然后进行对轮播图的管理,项目的管理和专业的管理(后端所需要的文件目录)
4.设计相应的前端页面(在page.json文件夹中给出了所需要设计页面的前端文件)
5.后台数据在若依管理系统中可以进行查看与管理
4.2.关键实现的数据流程图
4.3.实现重要功能的代码
实现发布项目的具体代码如下所示
前端代码
通过使用 Vue.js 框架和 Element UI 组件库构建的前端对话框(Dialog)页面的代码片段。用户可以输入标题和内容,并选择一张图片,这是用户发表项目的实现
后端代码
使用Spring Boot框架编写的RESTful控制器类,名为SysNoticeController,它继承自BaseController。这个控制器类负责处理与系统通知公告(SysNotice)相关的HTTP请求,用于管理系统通知公告
5.附加特点的设计与展示
5.1.设计的创意独到之处,这个设计的意义
在用户的注册页面添加了可以选择自己专业的页面,意义为在项目发布的时候同学们可以根据自己所处的专业更高效的去挑选自己所要合作的项目
5.2.实现思路
5.2.1.在ruoyi管理系统上生成专业选项
5.2.2.将数据导入到数据库,然后对该表进行操作
5.3最重要的代码片段
(这段代码用于户角色的授权和获取部门的树状结构列表)
(这段代码使用Element UI的
5.4实现效果展示
用户注册的时候可以进行专业的选择
6.目录说明和结构说明
首先请根据博客《[精简]RuoYi开发实战-搭建开发环境》进行环境的安装,具体也可以观看bilibili的教程
1.目录结构
(如下图所示,RuoYi-Vue-master作为前端,sql用于链接数据库,然后在,VScode打开ruoyi-ui打开前端,最后在Hbuilder X中进行App的运行,需要配置好RuoYi环境)
(如果后端没有成功开启,可以在命令行中输入services.msc确保mysql和redis成功启动)
2. 在Navicat中导入数据库。
- 修改配置文件:将url修改为自己电脑中所导入库的路径。
4.然后就可以在HBuilder中顺利运行。
7.单元测试
测试工具:IDEA
学习单元测试过程:
(1)B站搜索单元测试的相关内容,并根据视频的内容进行简单的单元测试编写
(2)浏览器搜索单元测试的相关教程,与在B站所学的知识互为补充,加深对单元测试的理解
(3)在IDEA上编写代码并进行单元测试,例如新建一个三角形的类,代码为判断三角形的种类,编写测试代码
部分单元测试代码:
package com.ruoyi.web.controller.system;
import static com.ruoyi.common.core.domain.AjaxResult.MSG_TAG;
import static org.mockito.Mockito.;
import static org.junit.jupiter.api.Assertions.;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.RegisterBody;
import com.ruoyi.framework.web.service.SysRegisterService;
import com.ruoyi.system.service.ISysConfigService;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.http.ResponseEntity;
public class SysRegisterControllerTest {
@Mock
private SysRegisterService registerService;
@Mock
private ISysConfigService configService;
@InjectMocks
private SysRegisterController controller;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@AfterEach
void tearDown() {
}
@Test
void testRegisterSuccess() {
// Arrange
RegisterBody user = new RegisterBody();
user.setUsername("testUser");
user.setPassword("testPassword");
when(configService.selectConfigByKey("sys.account.registerUser")).thenReturn("true");
when(registerService.register(user)).thenReturn("");
// Act
AjaxResult response = controller.register(user);
// Assert
assertTrue(response.isSuccess());
}
@Test
void testRegisterFailureDueToConfig() {
// Arrange
RegisterBody user = new RegisterBody();
user.setUsername("testUser");
user.setPassword("testPassword");
when(configService.selectConfigByKey("sys.account.registerUser")).thenReturn("false");
// Act
AjaxResult response = controller.register(user);
String code = response.get("code").toString();
if (code.equals("500"))
{
System.out.println(response.get(MSG_TAG));
}else
{
System.out.println(response.get(MSG_TAG));
}
}
@Test
void testRegisterFailureDueToService() {
// Arrange
RegisterBody user = new RegisterBody();
user.setUsername("testUser");
user.setPassword("testPassword");
when(configService.selectConfigByKey("sys.account.registerUser")).thenReturn("true");
when(registerService.register(user)).thenReturn("Username already exists");
// Act
AjaxResult response = controller.register(user);
String code = response.get("code").toString();
if (code.equals("500"))
{
System.out.println(response.get(MSG_TAG));
}else
{
System.out.println(response.get(MSG_TAG));
}
// Assert
//assertEquals(200, response.get("code"));
//assertFalse(response.isSuccess());
//assertEquals("Username already exists", response.get(MSG_TAG));
}
@Test
void register() {
}
}
测试的函数:setUp()
思路:
·使用 MockitoAnnotations.openMocks(this) 来初始化被注入的mock对象
测试的函数:testRegisterSuccess()
思路:
·创建一个 RegisterBody 对象并设置用户名和密码
·使用Mockito模拟配置服务返回注册功能开启的状态
·模拟注册服务成功返回空字符串
·调用控制器的注册方法并验证返回的 AjaxResult 是否表明成功(response.isSuccess() 为真
测试的函数:testRegisterFailureDueToConfig()
思路:
·创建一个 RegisterBody 对象
·模拟配置服务返回注册功能关闭的状态
·调用控制器的注册方法并获取响应
·根据响应的状态码输出对应的消息(未进行断言,主要用于调试信息)
测试的函数:testRegisterFailureDueToService()
思路:
·创建一个 RegisterBody 对象
·模拟配置服务返回注册功能开启的状态
·模拟注册服务返回“用户名已存在”的错误信息
·调用控制器的注册方法并获取响应
·输出响应的状态码及消息(未进行断言,主要用于调试信息)
如何考虑各种情况
·确保用户在正常情况下能够正常使用
·用户输入最大值、最小值、特殊符号和空输入时系统能够应对
·用户输入错误数据时系统能够正常处理错误并进行修正
应对未来测试人员的办法
·在发生错误或系统问题后,进行回顾分析,评估现有测试是否有效,识别需要改进的地方
·写代码注释,编写清晰的文档,以便后续维护和更新
·获取用户对app的反馈,了解不足之处,并进行更新、优化
·使用覆盖率工具, 确保测试用例覆盖大部分代码路径,识别未覆盖的关键部分
8.Github的代码签入记录
9.遇到的代码模块异常或结对困难及解决方法
9.1IDEA无法解析符号问题
问题描述:
使用IDEA进行单元测试时java代码出现无法解析符号的情况
做过哪些尝试尝试:
(1)尝试清理项目并重新构建
(2)更新IDEA
(3)在项目结构里选择不同的JDK文件
是否解决:
是
有何收获:
(1)对IDEA的功能有更加深入的了解,通过尝试不同的解决方案,更加熟悉了 IntelliJ IDEA 的项目结构设置和如何管理 JDK
(2)学习了常见的问题排查步骤,在解决此类问题时,明确了常用的排查步骤,比如清理和重建项目、检查 JDK 配置、更新 IDE 等
(3)建立了备份的意识,在处理项目配置时,意识到了定期备份重要的项目设置和文件的重要性,尤其是在做大规模修改之前。这样可以避免由于配置错误而导致长时间的调试工作
9.2后端接口异常问题
问题描述:
app的注册页面显示后端接口异常
做过哪些尝试尝试:
(1)查看后端接口文档,确认请求参数是否正确
(2)查看应用的错误日志,寻找异常堆栈信息
(3)修改application-buird.yml文件的url
是否解决:
是
有何收获:
(1)修改配置文件中的 URL 体现了环境变量的重要性,确保它们与后端服务匹配,以避免类似的问题再次发生
(2)积累了实战经验,通过实际操作,对后端服务的运行机制有了更直观的了解
(3)提升了错误日志的分析能力,加深对接口文档的理解