构建和测试
本页面说明 Fess 的构建方法、测试方法、 发布包的创建方法。
构建系统概述
Fess 使用 Maven 作为构建工具。 Maven 自动化依赖关系管理、编译、测试和打包。
pom.xml
Maven 的配置文件。位于项目的根目录。
主要配置内容:
项目信息(groupId、artifactId、version)
依赖库
构建插件
配置文件
基本构建命令
清理构建
删除构建产物后重新构建:
mvn clean compile
创建包
创建可执行的 JAR 文件:
mvn package
产物生成在 target/ 目录:
target/
├── fess-15.3.x.jar
└── fess-15.3.x/
完整构建
执行清理、编译、测试、打包的所有步骤:
mvn clean package
下载依赖
下载依赖库:
mvn dependency:resolve
下载 OpenSearch 插件
下载 OpenSearch 和必需插件:
mvn antrun:run
Note
此命令在设置开发环境时或 更新插件时执行。
测试
Fess 使用 JUnit 实现测试。
单元测试的执行
执行所有单元测试
mvn test
执行特定的测试类
mvn test -Dtest=SearchServiceTest
执行特定的测试方法
mvn test -Dtest=SearchServiceTest#testSearch
执行多个测试类
mvn test -Dtest=SearchServiceTest,CrawlerTest
跳过测试
跳过测试进行构建的情况:
mvn package -DskipTests
Warning
开发期间不要跳过测试,务必执行。 创建 PR 之前,请确认所有测试都通过。
集成测试的执行
执行包括集成测试在内的所有测试:
mvn verify
测试的编写
单元测试的创建
测试类的放置
将测试类放置在 src/test/java/ 下。 包结构与主代码相同。
src/
├── main/java/org/codelibs/fess/app/service/SearchService.java
└── test/java/org/codelibs/fess/app/service/SearchServiceTest.java
测试类的基本结构
package org.codelibs.fess.app.service;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class SearchServiceTest {
@Test
public void testSearch() {
// Given: 测试前提条件
SearchService service = new SearchService();
String query = "test";
// When: 执行被测试对象
SearchResponse response = service.search(query);
// Then: 验证结果
assertNotNull(response);
assertTrue(response.getResultCount() > 0);
}
}
测试的生命周期
import org.junit.jupiter.api.*;
public class MyServiceTest {
@BeforeAll
static void setUpClass() {
// 所有测试前执行一次
}
@BeforeEach
void setUp() {
// 每个测试前执行
}
@Test
void testSomething() {
// 测试
}
@AfterEach
void tearDown() {
// 每个测试后执行
}
@AfterAll
static void tearDownClass() {
// 所有测试后执行一次
}
}
断言
使用 JUnit 5 的断言:
import static org.junit.jupiter.api.Assertions.*;
// 等价性
assertEquals(expected, actual);
assertNotEquals(unexpected, actual);
// null 检查
assertNull(obj);
assertNotNull(obj);
// 布尔值
assertTrue(condition);
assertFalse(condition);
// 异常
assertThrows(IllegalArgumentException.class, () -> {
service.doSomething();
});
// 集合
assertIterableEquals(expectedList, actualList);
使用 Mock
使用 Mockito 创建 Mock:
import static org.mockito.Mockito.*;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(MockitoExtension.class)
public class SearchServiceTest {
@Mock
private SearchEngineClient searchEngineClient;
@Test
public void testSearch() {
// Mock 设置
when(searchEngineClient.search(anyString()))
.thenReturn(new SearchResponse());
// 执行测试
SearchService service = new SearchService();
service.setSearchEngineClient(searchEngineClient);
SearchResponse response = service.search("test");
// 验证
assertNotNull(response);
verify(searchEngineClient, times(1)).search("test");
}
}
测试覆盖率
使用 JaCoCo 测量测试覆盖率:
mvn clean test jacoco:report
报告生成在 target/site/jacoco/index.html。
代码质量检查
Checkstyle
检查编码风格:
mvn checkstyle:check
配置文件在 checkstyle.xml。
SpotBugs
检测潜在的错误:
mvn spotbugs:check
PMD
检测代码质量问题:
mvn pmd:check
执行所有检查
mvn clean verify checkstyle:check spotbugs:check pmd:check
创建发布包
创建发布包
创建用于发布的包:
mvn clean package
生成的产物:
target/releases/
├── fess-15.3.x.tar.gz # Linux/macOS 用
├── fess-15.3.x.zip # Windows 用
├── fess-15.3.x.rpm # RPM 包
└── fess-15.3.x.deb # DEB 包
创建 Docker 镜像
创建 Docker 镜像:
mvn package docker:build
生成的镜像:
docker images | grep fess
配置文件
可以使用 Maven 配置文件为不同环境应用不同的设置。
开发配置文件
使用开发配置进行构建:
mvn package -Pdev
生产配置文件
使用生产配置进行构建:
mvn package -Pprod
快速构建
跳过测试和检查进行快速构建:
mvn package -Pfast
Warning
快速构建仅用于开发中的确认。 创建 PR 之前,务必执行完整构建。
CI/CD
Fess 使用 GitHub Actions 执行 CI/CD。
GitHub Actions
配置文件在 .github/workflows/ 目录。
自动执行的检查:
构建
单元测试
集成测试
代码风格检查
代码质量检查
本地 CI 检查
创建 PR 之前,可以在本地执行与 CI 相同的检查:
mvn clean verify checkstyle:check
故障排除
构建错误
错误: 依赖下载失败
# 清除 Maven 的本地仓库
rm -rf ~/.m2/repository
mvn clean compile
错误: 内存不足
# 增加 Maven 的内存
export MAVEN_OPTS="-Xmx2g -XX:MaxPermSize=512m"
mvn clean package
错误: Java 版本过旧
请使用 Java 21 及以上:
java -version
测试错误
测试超时
延长测试超时时间:
mvn test -Dmaven.test.timeout=600
OpenSearch 未启动
确认端口,如果正在使用则更改:
lsof -i :9201
依赖问题
依赖冲突
确认依赖树:
mvn dependency:tree
排除特定的依赖:
<dependency>
<groupId>org.example</groupId>
<artifactId>example-lib</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>conflicting-lib</groupId>
<artifactId>conflicting-lib</artifactId>
</exclusion>
</exclusions>
</dependency>
构建的最佳实践
定期清理构建
定期执行清理构建,避免构建缓存问题:
mvn clean package
测试的执行
提交前务必执行测试:
mvn test
代码质量检查
创建 PR 之前检查代码质量:
mvn checkstyle:check spotbugs:check
依赖更新
定期更新依赖:
mvn versions:display-dependency-updates
利用构建缓存
为缩短构建时间,利用 Maven 的缓存:
# 如果已编译则跳过
mvn compile
Maven 命令参考
常用命令
# 清理
mvn clean
# 编译
mvn compile
# 测试
mvn test
# 打包
mvn package
# 安装(注册到本地仓库)
mvn install
# 验证(包括集成测试)
mvn verify
# 解析依赖
mvn dependency:resolve
# 显示依赖树
mvn dependency:tree
# 显示项目信息
mvn help:effective-pom
下一步
理解了构建和测试方法后,请参阅以下文档: