Maven
运行DEMO可以在百度网盘中获取:通过网盘分享的文件:https://pan.baidu.com/s/1Ut9-STQL_8ColkAa4-kMkQ?pwd=edar
Maven
Apache Maven是一个项目管理和构建工具,它基于项目对象模型(POM)的概念,通过一小段描述信息来管理项目的构建
作用
- 方便快捷的管理项目依赖的资源(jar包),避免版本冲突问题
- 提供标准、统一的项目结构
- 标准跨平台(Linux、Windows、MacOS)的自动化项目构建方式
仓库
用于存储资源,管理各种jar包
- 本地仓库:存放在自己计算机上的目录
- 中央仓库:由Maven团队维护的全球唯一的仓库。仓库地址:https://repo1.maven.org/maven2/
- 远程仓库(私服):一般由公司团队搭建的私有仓库
安装
安装步骤:
- 解压
apache-maven-x.x.x-bin.zip - 配置本地仓库:修改conf/setting.xml中的
为一个指定目录
<localRepository>E:\develop\apache-maven-x.x.x\mvn-reop</localRepository>
3. 配置阿里云私服:修改conf/setting.xml中的
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
4. 配置环境变量:MAVEN_HOME为maven的解压目录,并将其bin目录加入PATH环境变量
配置Maven环境
当前工程
- 选中IDEA中File➡Setting➡Build,Execution,Deployment➡Build Tools➡Maven
- 设置IDEA使用本地安装的Maven,并修改配置本地文件及本地仓库路径
- 设置Runner中的JDK版本
- 设置字节码版本File➡Setting➡Build,Execution,Deployment➡Complier➡Java Compiler➡project bytecode version
全局工程
- 首先需要退出项目File➡close project
- 进入IDEA开始界面
- 找到Customize➡All settings
- 重复当前工程的操作
创建Maven项目
- 创建模块,选择Maven,点击Next
- 填写模块名称,坐标信息,点击Finish,创建完成
当创建完成后,编写Hello World测试环境配置是否成功
如果编译后出现java: 错误: 不支持发行版本 6报错信息,则需要找到当前项目的pom.xml文件,添加如下代码
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
17表示JDK版本
完整代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.norlcyan</groupId>
<artifactId>test01</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
</project>
注意:修改完代码,需要在IDEA中重新加载配置文件,IDEA会在右上角出现一个M的标志,点击即可
Maven坐标
- Maven中的坐标是资源的唯一标识,通过该坐标可以唯一定位资源位置
- 使用坐标来定义项目或引入项目中需要的依赖
坐标的组成
- groupId:定义当前Maven项目隶属组织名称(通常是域名反写,例如:app.netlify.norlcyan)
- artifactId:定义当前Maven项目名称(通常是模块名称,例如:order-service、goods-service)
- version:定义当前项目的版本号
<groupId>app.netlify.norlcyan</groupId>
<artifactId>test01</artifactId>
<version>1.0-SNAPSHOT</version>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
依赖管理
- 依赖:指当前项目运行所需要的jar包,一个项目中可以引入多个依赖
- 配置:
1. 在
pom.xml中编写标签 2. 在 标签中使用 引入坐标 3. 定义坐标的groupId、artifactId、version 4. 点击刷新按钮,引入最新的坐标
注意:
- 如果本地仓库中没有依赖的jar包,代码不会提示,且pom.xml文件会报红,当填写完依赖包的详细信息后,点击刷新会自动下载缺少的包
- 要想知道依赖包的详细信息,可以访问https://mvnrepository.com/查看
依赖传递
- Maven中的依赖具有传递性
- 直接依赖:在当前项目中通过依赖配置建立的依赖关系
- 间接依赖:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源
依赖范围
依赖的jar包,默认情况下,可以在任何地方使用。可以通过
作用范围:
- 主程序范围有效(main文件夹范围内)
- 测试程序范围有效(test文件夹范围内)
- 是否参与打包运行(package指令范围内)
| scope值 | 主程序 | 测试程序 | 打包 | 范例 |
|---|---|---|---|---|
| compile(默认) | Y | Y | Y | log4j |
| test | - | Y | - | junit |
| provided | Y | Y | - | servlet-api |
| runtime | - | Y | Y | jdbc驱动 |
示例:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
生命周期
Maven的生命周期就是为了所有的maven项目构建过程进行抽象和统一
Maven有三套相互独立的生命周期:
- clean:清理工作
- default:核心工作,如:编译、测试、打包、安装、部署等
- site:生成报告、发布站点等
生命周期阶段:
- clean:移除上一次构建生成的文件
- complie:编译项目源代码
- test:使用合适的单元测试框架进行测试(junit)
- package:将编译后的文件打包,如:jar、war等
- install:安装项目到本地仓库
测试
- 测试:是一种用来促进鉴定软件的正确性、完整性、安全性和质量的过程
- 阶段划分:单元测试、集成测试、系统测试、验收测试
- 测试方法:白盒测试、黑盒测试以及灰盒测试
白盒测试:
- 清楚软件内部结构、代码逻辑
- 用于验证代码、逻辑正确性
黑盒测试:
- 不清楚软件内部结构、代码逻辑
- 用于验证软件的功能、兼容性等方面
灰盒测试:
- 结合了白盒测试和黑盒测试的特点,既关注软件的内部结构又考虑外部表现(功能)
单元测试:
- 介绍:对软件的基本组成单位进行测试,最小测试单位
- 目的:检验软件基本组成单位的正确性
- 测试人员:开发人员
- 白盒测试
集成测试:
- 将已分别通过测试的单元,按设计要求组合成系统或子系统,再进行的测试
- 目的:检查单元之间的协作是否正确
- 测试人员:开发人员
- 灰盒测试
系统测试:
- 介绍:对已经继承好的软件系统进行彻底的测试
- 目的:验证软件系统的正确性、性能是否满足指定的要求
- 测试人员:测试人员
- 黑盒测试
验收测试:
- 介绍:交付测试,是针对用户需求、业务流程进行的正式的测试
- 目的:验证软件系统是否满足验收标准
- 测试人员:客户/需求方
- 黑盒测试
单元测试
- 单元测试就是针对最小的功能单元(方法),编写测试代对其正确性进行测试
- Junit是最流行的Java测试框架之一,提供了一些功能,方便程序进行单元测试(第三方公司提供)
- main方法测试的弊端:
- 测试代码与源代码未分开,难以维护
- 一个方法测试失败,影响后面方法的运行
- 无法自动化测试,得到测试报告
示例:
public class Test {
public static void main(String[] args) {
// 查询所有的测试方法
findALLStudent();
// 添加学生
addStudent();
// 修改学生
updateStudent();
// 删除学生
deleteStudent();
}
// 测试删除学生
private static void deleteStudent() {...}
// 测试修改学生
private static void updateStudent() {...}
// 测试添加学生的方法
private static void addStudent() {...}
// 查询所有的学生数据
private static void findALLStudent() {...}
}
JUnit
初次使用JUnit
- 在pom.xml中,引入JUnit的依赖:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.1</version>
</dependency>
- 在test/java目录下,创建测试类,并编写对应的测试方法,并在方法上声明@Test注解
@Test
public void testGetAge() {
Integer age = new UserSerive().getAge("110002200505091218")
System.out.println(age)
}
注意:JUnit单元测试类名命名规范为XxxxTest【规范】。Junit单元测试的方法,必须声明为public void 【规定】
- 运行单元测试(测试通过:绿色;测试失败:红色)
package app.netlify.norlcyan;
import org.junit.jupiter.api.Test;
public class UserServiceTest {
@Test
public void testGetAge() {
UserService userService = new UserService();
Integer age = userService.getAge("110002200505091218");
System.out.println(age);
}
}
断言
JUnit提供了一些辅助方法,用来确定被测试方法是否按照预期的效果正常工作,这种方式称为断言
| 断言方法 | 描述 |
|---|---|
| Assertions.assertEquals(Object exp, Object act, String msg) | 检查两个值是否相等,不相等报错 |
| Assertions.assertNotEquals(Object unexp, Object act, String msg) | 检查两个值是否不相等,相等报错 |
| Assertions.assertNull(Object act, String msg) | 检查对象是否为null,不为null报错 |
| Assertions.assertNotNull(Object act, String msg) | 检查对象是否不为null,为null报错 |
| Assertions.assertTrue(boolean condition, String msg) | 检查条件是否为true,不为true报错 |
| Assertions.assertFalse(boolean condition, String msg) | 检查条件是否为false,不为false报错 |
| Assertions.assertThrows(Class expType, Executable exec, String msg) | 检查两个对象引用是否相等,不相等报错 |
示例:
@Test
public void testGenderWithAssert() {
UserService userService = new UserService();
String gender = userService.getGender("100000200010011011");
// 断言
Assertions.assertEquals("男",gender);
}
常见注解
在JUnit中还提供了一些注解,还增强其功能,常见的注解有以下几个:
| 注解 | 说明 | 备注 |
|---|---|---|
| @Test | 测试类中的方法用它修饰才能成为测试方法,才能启动执行 | 单元测试 |
| ParameterizedTest | 参数化测试的注解(可以让单个测试运行多次,每次运行时仅参数不同) | 用了该注解就不需要@Test注解了 |
| @ValueSource | 参数化测试的参数来源,赋予测试方法参数 | 与参数化测试注解配合使用 |
| @DisplayName | 指定测试类、测试方法显示的名称(默认为类名、方法名) | |
| @BeforeEach | 用来修饰一个实例方法,该方法会在每一个测试方法执行之前执行一次 | 初始化资源(准备工作) |
| @AfterEach | 用来修饰一个实例方法,该方法会在每一个测试方法执行之后执行一次 | 释放资源(清理工作) |
| @BeforeAll | 用来修饰一个静态方法,该方法会在所有测试方法之前只执行一次 | 初始化资源(准备工作) |
| @AfterAll | 用来修饰一个静态方法,该方法会在所有测试方法之后只执行一次 | 释放资源(清理工作) |
示例:
@DisplayName("测试性别") // 控制台会显示该测试的名称为”测试性别“
@ParameterizedTest
@ValueSource(strings = {"100000200010011011","100000200010011041","100000200010011051"})
public void testGender2(String idCard) {
UserService userService = new UserService();
String gender = userService.getGender(idCard);
// 断言
Assertions.assertEquals("男",gender); // 测试三次,第二次是错误结果
}
企业开发规范
原则:编写测试方法时,要尽可能的覆盖业务方法中所有可能的情况(尤其是边界值)
实际开发中,有可能会编写大量的单元测试,难免出现缺漏某些情况。为了防止出现这种情况,可以借助AI生产测试代码。
在IDEA插件中安装通义灵码,并且登录账户(免费)。然后在需要测试的代码上点击生成单元测试即可。