JavaWeb中Web后端基础(Maven+单元测试笔记)

文章完善进度100%

1. 问题一⭐

Maven是什么?3个优点?

Maven是一个用于“管理与构建Java项目”的工具(管理项目与项目依赖的工具)。使用Maven主要是因为下面3点:

依赖管理:之前用到jar包时要去官网下载,然后……,而使用Maven更简单,直接在src同级新建一个pom.xml文件,根据官方配置初始代码,然后加一段要使用的jar包对应的dependency代码就行!

项目构建:大致意思就是能一键进行编译、测试、打包与发布……

点击那个compile就会对这个项目的所有代码进行编译操作,然后就会生成一个target目录,那classes目录下存放的就是编译后的字节码文件。

package就是打包,点击后会生成一个jar文件,其它命令同理……
统一结构:使用不同的java编程工具生成的文件目录结构不同,此时引入Maven就可以解决这个问题了。

2. 问题二

Maven模型组成(3个)?仓库存啥的?仓库分类?

模型组成如下所示,就是下面图片中那3个绿色的东西!

比如下面图片就是一个初始默认的pom.xml文件(第7-16行就对应第1个绿色部分POM,第18行那标签内就是第2个绿色部分Dependency)

那个构建项目周期下面对应的插件就是下面图片中对应的Lifecycle中内容。

最右边那个仓库是用来存放各种各样的jar包资源的(先查本地、没的话再查私服、还没有就只能去查中央仓库,查到后下载到本地仓库进行使用)

3. 问题三

Maven的安装流程?IDEA集成Maven?

自己去资源里找到这个文件,然后按下面步骤进行安装就行。(第二步那目录要自己新建,用来存jar包的)

最后只要在cmd中进行一下验证就行,你运行下mvn -v代码,有输出就说明没问题了!
针对单个项目,直接去设置里面配置下面图片中的3个东西就行了。

如果想让之后new的所有project都用上Maven,可以如下所示配置!
①先关闭项目,到启动页面那All settings中进行设置。

②然后搜索Maven进行配置

4. 问题四⭐

创建Maven项目(项目结构)?

①选择New Project,然后在空项目中配置name后创建就行!(选择java时可以直接配置Maven,但开发中一般是在模块级配置maven)

②点击file,去项目结构那选择jdk17

③选择新建立模块,然后配置下面这些东西(name、Build system、jdk)!

④然后确定就能完成基本配置了,会生成如下那个maven-project01文件夹(现在就能在那main中的java文件夹中写java代码了)。

目录结构介绍如下图:

5. 问题五⭐

Maven中坐标的介绍与组成?

右边两份代码一份是指向Maven这个资源的,一个是指向外部的其它资源的。(组成:组织名、项目名、2类版本号)

6. 问题六

导入Maven项目到idea中?

方式一:直接打开文件是没有用的,下面中project01是上节课自己创建的,02与03是别人的,直接打开(拖到project01同级目录)是没有maven项目标识。

要选择最上面的File,再按图片中步骤配置才有用(导入时要选择pom.xml文件进行导入)。

方式二:导入时都要选择pom.xml文件,这是maven项目的说明文件。

7. 问题七

pom.xml的依赖配置?排除依赖方法?

写完成后一定要点击一个对应依赖右上角那刷新按钮才有用,否则会一直变红报错!(mvnrepository.com可以搜索一些常用的依赖,新建springboot项目的时候也可以勾选相关依赖)

你也可以在dependencies中右键选择Generate。

然后选择Dependency就可以进行依赖的搜索了

具体代码例子如下所示:(与properties同级写个dependencies标签,里面专门来写想下载的 依赖)

下载完成后右边应该能看到下载的东西,这就说明成功了(依赖里面的那几个小依赖就这个依赖所依赖的依赖,会全部下载,如果不想下载这么多,就要学会排除依赖)

排除依赖的详细步骤如下图所示,只需加个excleusions的标签就行!(经常用于解决版本冲突问题,还有一个原因是有些库写得比较“臃肿”,它为了支持多种功能,引入了大量的依赖,但你其实只用到了它的一小块功能。)

8. 问题八⭐

Maven生命周期?生命周期的执行与特点?

每个生命周期又分成多个阶段,下面标红色的阶段是重点阶段,我们主要学习的。

5个重要阶段的详细介绍

还有一个要注意的点如下图,有3套生命周期,比如运行install时第2个生命周期的install前面的阶段都会运行,但不会运行第1个生命周期中的那clean……、

执行生命周期有2种方式,你可以直接双击上面图片右边那对应的阶段,或者使用命令行命令,详细的命令行命令如下所示:mvn clean,直接修改后面那阶段就能换其它命令。
点击compile阶段命令,就是进行编译,会生成一个target文件夹!
你运行代码时,它会生成一个target文件,里面放了编译后的class文件,运行clean命令后,就会直接把这个target文件夹删除掉!

点击package命令就会进行打包,生成一个jar包,也是放在target文件夹下。
test命令后面讲完单元测试再讲。
点击install命令后会安装到本地仓库,就是第一次下载maven时定义的仓库,文件夹名为mvn_repo,我这电脑在D:\apache-maven-3.9.4\mvn_repo目录下。
其实运行那生命周期各个阶段时,就是运行Plugins下面的那些扫插件,然后转成对文件的一些处理。

9. 问题九⭐

什么是测试?4个阶段?3大方法?各阶段对应方法?

单元测试就是测试“方法/函数”!还有第4个验收测试不是用户,是由“甲方”进行的。

常见的3大测试方法如下所示:

每个阶段常用的测试方法如下图所示:

10. 问题十⭐

什么是单元测试?JUnit测试框架是什么?为什么引入?

单元测试是用来调试方法的,企业中是用JUnit测试框架进行测试,这个JUnit是最流行的Java测试框架一,提供了一些功能,方便程序进行单元测试(第三方公司提供)。为什么不直接在main方法中进行方法的调用然后测试?

而使用JUnit测试可以完美解决上面那3个问题

11. 问题十一⭐

JUnit框架测试流程?

①首先,要先在pom.xml文件中引入JUnit的依赖
具体引入代码如下所示:

1
2
3
4
5
6
7
<!--Junit单元测试依赖-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.1</version>
<scope>test</scope>
</dependency>

②建立如下图所示的目录结构,UserService类中写了两个要测试的方法,而UserServiceTest是测试这个要测试方法的方法!(一般测试类都写在test文件夹下)

其中,UserService中的代码如下所示(要测试的方法):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  package online.sunwei;

import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;

public class UserService {
public Integer getAge(String idCard) {
// 校验身份证号码非空且长度为18位
if (idCard == null || idCard.length() != 18) {
throw new IllegalArgumentException("无效的身份证号码");
}

// 截取出生日期(第7-14位)
String birthday = idCard.substring(6, 14);
// 解析出生日期字符串为LocalDate对象
LocalDate birthDate = LocalDate.parse(birthday, DateTimeFormatter.ofPattern("yyyyMMdd"));
// 计算当前日期与出生日期的年份差(即年龄)
return Period.between(birthDate, LocalDate.now()).getYears();
}

/**
* 根据身份证号计算用户性别
* @param idCard 身份证号码(18位)
* @return 性别(男/女)
*/
public String getGender(String idCard) {
// 校验身份证号码非空且长度为18位
if (idCard == null || idCard.length() != 18) {
throw new IllegalArgumentException("无效的身份证号码");
}

// 截取第17位字符(性别码,奇数为男,偶数为女)
// 原代码substring(16,17)是正确的,此处修正原图片中可能的笔误逻辑
int genderCode = Integer.parseInt(idCard.substring(16, 17));
return genderCode % 2 == 1 ? "男" : "女";
}
}

而UserServiceTest中的代码如下所示(测试.java文件命名要符合规范,以“XxxxxTest.java”命名,必须声明public void):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package online.sunwei;

import org.junit.jupiter.api.Test;

public class UserServiceTest {
@Test
public void testGetAge(){
Integer age = new UserService().getAge("110002200505091218");
System.out.println(age);
}

@Test
public void testgetGender(){
String gender = new UserService().getGender("110002200505091218");
System.out.println(gender);
}
}

③可以点击运行单个方法,或者运行类来运行类中的全部方法(第一个绿色勾是运行全部方法,后面两个是运行单独的方法)

④然后就能出来运行结果了,右边那会显示通过4个,失败2个,右边那6个就是测试方法……

12. 问题十二⭐

什么是断言?如何使用?

单元测试运行结果为”绿色“也不一定说明测试通过,只能说明写代码的语法没有问题,但可能代码的逻辑是错误的,无法实现需求,此时就要用到断言了。

下面代码如果能运行,且运行结果为“男”,就不报错!(第1个参数是期望结果,第2个参数是实际运行结果)

13. 问题十三

JUnit框架中常见注解?

具体代码例子(资源相关):
运行测试类时,那All的只有最前面与最后面输出了一下,其它地方不输出(后面那4个注解主要是做一些资源的准备与释放工作)。

具体代码例子(参数相关,会重复用不同的参数运行3次):

为了区别不同测试类与方法,可以在测试类/方法上面为这东西命名:

比如你为一个用户测试类与方法命名了,然后运行结果就更有可观性。

14. 问题十四

测试方法覆盖率?

上面加了断言后并不能认为你写的代码测试通过了,虽然语法(测试)、逻辑(断言)都没有问题,但测试用例可能不全面!

覆盖率表(运行测试类时点击第3个就能统计覆盖率)

运行结果如下(说明没有写与HelloWorld相关的测试类,有与UserService相关的测试类,但其中只有50%的方法被测试了 ,Line是所有代码的覆盖率,只有37%,Branch没有100%是因为有些if语句中的内容没有执行……)

正常情况下你不可能想全面的,应该结合ai来生成全部的单元测试?
实际开发中,我们通常是借用ai来生成单元测试(直接在java文件那点击“生成单元测试“,然后你复制后放到test文件夹下面去):

15. 问题十五

依赖如何控制生效范围?test生命周期?

为了确保测试代码写在test文件夹中,引入“依赖范围”的概念。(按下面流程规定测试范围后,main文件夹中写测试方法就没用了)

点击那个test阶段后,就会进行所有的单元测试,如何打包时不想让它进行test,可以点击那相🚫符号(图片中三条线的yellow图标)。