当前位置: 首页 > news >正文

【JUnit实战3_19】第十章:用 Maven 3 运行 JUnit 测试(下)

JUnit in Action, Third Edition

《JUnit in Action》全新第3版封面截图

写在前面
本篇继续梳理 Maven 知识点。本以为没什么可以复盘的,实测过程中却遇到了好几个不大不小的坑,一并记录下来,提醒自己不要自以为是,毕竟温故才能知新。

10.4 常用插件

从插件的角度看,Maven 也是一个通过运行插件来构建源代码的构建环境。Maven 构建中的每个任务都是由相应的插件来完成的。本节重点介绍了三个插件:maven-compiler-pluginmaven-surefire-pluginmaven-site-plugin,分别负责项目的编译、单元测试和项目文档生成。

另外,如果刚才的 Maven 项目骨架需要导入 EclipseMaven 也专门提供了一个 maven-eclipse-plugin 插件方便一键导入 Eclipse,无需手动安装,只要在创建好骨架后再运行 mvn eclipse:eclipse 即可。该插件会生成 Eclipse 识别项目需要的两个文件:.project.classpath

这是用最新版的 Eclipsev2025-12 M1)导入 Maven 项目、并打开 pom.xml 后的实测截图:

Fig10.3

踩坑备忘:慎用 Eclipse 的 exe 安装包

为了实测导入 Eclipse 的效果,安装 Eclipse 时不小心下载了官方提供的 .exe 格式的安装包,结果又填错了 Java 21JRE 路径(应该详细到 bin 目录),导致安装完成后软件能从 GUI 界面启动、但从快捷方式或安装目录双击 eclipse.exe 文件打开就报错(报错提示也很奇葩):

Fig10.2

排查了很多地方,jar 包和里面的主类都是存在的,最后和老本本上的 Eclipse 仔细对比才找到根本原因:运行 exe 安装包时 JRE 路径不正确,导致最后的启动配置文件 eclipse.ini 缺了最关键的 -vm 参数。eclipse.ini 前后对比如下(节选):

# 更正前
-startup
plugins/org.eclipse.equinox.launcher_1.7.0.v20250519-0528.jar# 更正后
-vm
C:\Program Files\Java\jdk-21\bin
-startup
plugins/org.eclipse.equinox.launcher_1.7.0.v20250519-0528.jar

时隔多年,Eclipse 官网已经将熟悉的 zip 包下载链接放在了很不起眼的位置,取而代之的时 exe 安装包:运行后可以优先从线上匹配最新的 JDKJRE 版本,同时也方便插播硬广和捐款链接,可谓用心良苦……这个不大不小的坑也花了我大半个小时的宝贵时间,希望后来者能吸取教训。

10.4.1 编译器插件

maven-compiler-plugin 插件。每次运行 mvn compile 命令,其实就在调用该插件。编译前 Maven 还会经历一个验证阶段(对应命令 mvn validate),负责将 pom.xml 的依赖下载的本地,并引入项目的 classpath 中。而编译完成后的所有类文件则放入 target/classes/ 文件夹下。

该插件支持手动指定编译器支持的源代码版本,以及编译生成的字节码目标版本:

<build><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><version>2.3.2</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins>
</build>

可以看到,插件在 pom.xml 中的声明和项目依赖很像,之所以省略 groupId 标签,是因为这是 Maven 的核心标签,groupId 默认均为 org.apache.maven.plugins,配置时可以不写。

10.4.2 单元测试插件

maven-surefire-plugin 插件,它是命令 mvn test 运行背后调用的插件,负责执行具体的单元测试(不仅限于 JUnit 单元测试)。通常在执行测试前,还会先执行一个 clean 命令(即 mvn clean test),以消除历史编译内容对本次测试的潜在干扰。

由于 Maven 的测试执行能力是由 maven-surefire-plugin 实现的,它通过生命周期绑定与 mvn test 命令关联。当项目的默认配置不符合预期时(如命名不规范等),很可能运行 mvn test 命令会自动跳过测试,此时就必须显式配置 maven-surefire-plugin 插件方可执行单元测试。

该插件也可以指定筛选条件,使得符合某种命名规范的测试用例才会最终执行。例如只执行后缀为 -Test.java 的测试用例:

<build><plugins><plugin><artifactId>maven-surefire-plugin</artifactId><version>2.22.2</version><configuration><includes>**/*Test.java</includes></configuration></plugin></plugins>
</build>

更多手动配置详见 Maven 官方文档。

10.4.3 项目文档生成插件

maven-site-plugin 插件。该插件平时很少用到,但它可以根据配置自动生成项目文档,对应的命令是 mvn site,使用前需要先配置到 pom.xml

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-site-plugin</artifactId><version>3.12.1</version>
</plugin>

mvn site 运行成功后会在 target/site/ 目录下生成该项目的文档,实测时的新版本较原书中的 3.7.1 版更加简洁规范(注意:以下截图效果必须先手动添加上面补充的 developers 等非必填标签):

Fig10.4

10.4.4 生成单元测试报表

Maven 可以根据 JUnit 生成的 XML 格式的测试报表生成 HTML 格式的报表页。同理,该任务也是由一个名为 maven-surefire-report-plugin 插件完成的。虽然无需在 pom.xml 中单独声明,但由于 Maven 默认的构建阶段内,因此需要手动执行命令:

mvn surefire-report:report

最终会在 target/reports/ 文件夹中生成 HTML 格式的测试报表,其数据源是 JUnit 测试产生的原始格式(XML)报表,可以在 target/surefire-reports/ 下查看:

Fig10.6

新版报表效果如下:

Fig10.7

命令行和 IDE 在 Java 版本处理上的差异

实测发现,最新版的 pom.xml 中指定的 Java 版本为 17:

<maven.compiler.release>17</maven.compiler.release>

导入 IDEA 后项目结构自动选用我本机上的 JDK21,运行报表生成命令一切正常;但是从命令行运行该命令就会严格按上述设置的 17 执行(本地未安装 JDK17),于是运行报错:

Fig10.5

根本原因:安装 JDK21 时忘了同步更新 JAVA_HOME 的值,报错时还是 JDK11 所在的路径(太粗心)。

另外,Maven 官方文档也推荐这种显式声明 Java 发行版本的写法,否则 maven-compiler-plugin 默认还是按 Java 8 处理。

10.5 Maven 构建的生命周期

Maven 有三个内置的生命周期:

  • default:用于生成项目构件(artifact);
  • clean:用于清空项目构建产物;
  • site:用于生成标准化的项目文档。

每个生命周期都由若干个阶段组成。一个相对完整的 Maven 默认生命周期如下图所示:

Fig10.16

这里再次体现了 Maven 约定优于配置 的核心原则。Maven 会严格按照该顺序依次调用这些阶段,让它们依次执行。例如,执行 mvn compile 命令时,Maven 会先执行 Validate 验证阶段,然后再执行 Compile 阶段,完成项目源代码的编译工作。

10.6 实战演练:航班管理应用

本章的最后呼应“实战”主题,完整演示了如何利用 Maven 从零创建一个虚构的航班管理应用的全过程,其间还编写了一个单元测试,并最终将项目打包成 jar 文件、进而安装到本地 Maven 仓库。具体实战过程如下:

首先在 C:\junitbook\ 目录下打开命令行,运行以下 Maven 命令:

mvn archetype:generate -DgroupId=com.testeddatasystems.flights -DartifactId=flightsmanagement -DarchetypeArtifactid=maven-artifact-mojo

中途所有设置一律按默认设置执行,直接按回车键继续:

Fig10.9

运行成功后,就得到一个 flightsmanagement 文件夹:

Fig10.8

然后从 IDEA 导入该项目,效果如下:

Fig10.10

删除默认的 App.java 及其测试类 AppTest.java,新增一个乘客实体类 Passenger.java

package com.testeddatasystems.flights;public class Passenger {private String identifier;private String name;public Passenger(String identifier, String name) {this.identifier = identifier;this.name = name;}public String getIdentifier() {return identifier;}public String getName() {return name;}@Overridepublic String toString() {return "Passenger " + getName() +" with identifier: " + getIdentifier();}
}

然后将光标放到 Passenger 上,按 Ctrl + Shift + T 弹出新建单元测试的快捷窗口,按 Enter 继续后根据提示操作(测试类的名称都生成好了,只需按 Enter 确认)即可:

Fig10.11

Fig10.12

然后添加如下测试用例:

@Test
void testPassenger() {Passenger passenger = new Passenger("123-456-789", "John Smith");assertEquals("Passenger John Smith with identifier: 123-456-789",passenger.toString());
}

再从 Maven 侧边栏中执行命令 mvn clean install,将项目打包并安装到本地 Maven 仓库:

Fig10.13

最终,target 目录下新增了一个名为 flightsmanagement-1.0-SNAPSHOT.jarjar 文件;本地 Maven 库也多了一个对应的本地依赖:

Fig10.14

Fig10.15

小贴士

实战过程中尽量多用 IDEA 的各种键盘操作,尽量少通过鼠标完成操作,以提高构建效率。

http://www.dtcms.com/a/553148.html

相关文章:

  • wordpress 禁止过滤张家口seo
  • 网站建设的流程该怎么确定自己怎么设计logo制作
  • 3.游戏逆向-pxxx-对照UE源码和IDA分析GName偏移(ida中calloff开头地址的说明)
  • AR智能巡检:开启工业运维的“透视眼”
  • PhotoQt,一款轻量级图片浏览器
  • 什么是一级boot和二级boot
  • 网站开发师招聘网站建设几个要素
  • Java语言处理Js文件内容格式化
  • 力扣Hot100--哈希表--day01
  • 鸿蒙技术知多点,技术深入、鸿蒙开发实战分享(一)——下载功能按钮与全局悬浮窗联动实战开发
  • 安科瑞暖通空调解决方案可覆盖分体空调、中央空调和多联机等类型空调系统,有效帮助用户实现空调系统节能降本
  • 用php做购物网站视频网站建设 翰臣科技公司
  • 本地音乐库嫌麻烦?PlaylistDL+cpolar打造“随身听”云端曲库!
  • 巩义网站建设定制电子商务系统网站开发总结
  • Excel怎么在下拉菜单中选择计算方式?
  • PHY6252国产蓝牙低成本透传芯片BLE5.2智能灯控智能家居
  • unity之线框模式
  • h5游戏免费下载:小飞鱼?
  • 【设计模式】享元模式(Flyweight)大白话讲解!
  • seo网站优化知识网站设计师的工作环境
  • 浅谈onlyoffice开发全流程(一、基础介绍)
  • 金仓KRDS云数据库服务管控平台:构建高效智能的数据库运维体系
  • GMI Cloud:如何构建全球化高性能分布式推理服务?
  • Linux入门攻坚——52、drbd - Distribute Replicated Block Device,分布式复制块设备-1
  • Threat Report ATTCK Mapper(TRAM)安装与配置手册
  • java后端初始化模版
  • WebGPU深度学习前端:基于浏览器的分布式模型推理
  • 深入浅出:增强现实(AR)技术全解析
  • 【进程间通信】--- 匿名管道,命名管道
  • 温岭网站建设公司百度问问首页登录