You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot+Maven独立单元测试框架搭建及代码覆盖率检查问题求助

我来帮你搞定这个拆分业务代码和测试代码的问题——之前的方案踩坑大概率是因为Spring Boot默认打包的是可执行Jar,结构和普通Maven Jar不一样,导致测试项目没法正确依赖业务类。下面是一套亲测有效的方案,一步步来:

核心思路

我们的目标是让两个项目完全独立:一个只放业务代码,生成普通的Maven业务Jar;另一个只放单元测试代码,依赖这个业务Jar来执行测试,同时用Jacoco统计业务代码的覆盖率。这样既保持了代码整洁,又能正常跑测试和看覆盖率。

步骤1:改造业务代码项目(生成普通业务Jar)

Spring Boot默认的spring-boot-maven-plugin会把项目打包成可执行Jar,里面的类都在BOOT-INF/classes目录下,测试项目依赖的时候根本找不到这些类。所以我们要修改业务项目的pom.xml,让它同时生成普通业务Jar和可执行Spring Boot Jar:

<!-- 打包类型保持为jar -->
<packaging>jar</packaging>

<!-- 如果之前用spring-boot-starter-parent作为父项目,保留即可;如果不想用父项目,就用dependencyManagement导入Spring Boot依赖 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>你的Spring Boot版本</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>你的Spring Boot版本</version>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                    <configuration>
                        <!-- 给可执行Jar加个classifier,这样会生成两个Jar:xxx.jar(普通业务Jar)和xxx-exec.jar(可执行Jar) -->
                        <classifier>exec</classifier>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

修改完后,执行mvn clean install,就能在业务项目的target目录下看到两个Jar,我们的测试项目只需要依赖那个不带-exec后缀的普通Jar。

步骤2:创建独立的单元测试项目(TestNG + Spring Test)

新建一个Maven项目(不需要是Spring Boot项目,当然你也可以建Spring Boot项目,只要精简依赖就行),然后在pom.xml里配置依赖和插件:

<dependencies>
    <!-- 依赖你的业务项目 -->
    <dependency>
        <groupId>你的业务项目groupId</groupId>
        <artifactId>你的业务项目artifactId</artifactId>
        <version>对应版本号</version>
        <scope>test</scope>
    </dependency>

    <!-- TestNG测试框架依赖 -->
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.8.0</version>
        <scope>test</scope>
    </dependency>

    <!-- Spring Test支持,用来测试Spring组件(比如Service、Controller) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>你的Spring Boot版本</version>
        <scope>test</scope>
        <!-- 如果只用TestNG,排除JUnit相关依赖避免冲突 -->
        <exclusions>
            <exclusion>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter-api</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

<build>
    <plugins>
        <!-- TestNG执行插件,指定测试套件配置文件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.2.5</version>
            <configuration>
                <suiteXmlFiles>
                    <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
                </suiteXmlFiles>
            </configuration>
        </plugin>

        <!-- Jacoco插件,生成代码覆盖率报告 -->
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.10</version>
            <executions>
                <execution>
                    <id>prepare-agent</id>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                </execution>
                <execution>
                    <id>report</id>
                    <goals>
                        <goal>report</goal>
                    </goals>
                    <configuration>
                        <!-- 关键!指定业务项目编译后的class文件路径,Jacoco才能分析业务代码的覆盖率 -->
                        <classesDirectory>${project.basedir}/../业务项目名称/target/classes</classesDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

注意:classesDirectory的路径要根据你的项目实际位置调整,如果业务项目和测试项目是同级目录,用上面的相对路径就行;如果是其他结构,改成对应的绝对路径或者正确的相对路径。

步骤3:Jenkins上配置执行流程

在Jenkins里新建一个流水线或者自由风格项目,按以下顺序执行:

  1. 拉取业务代码项目,执行mvn clean install——把业务Jar安装到本地仓库(如果是团队协作,建议传到公司的Maven私服)
  2. 拉取测试代码项目,执行mvn clean test jacoco:report——运行TestNG测试并生成Jacoco覆盖率报告
  3. 在Jenkins的项目配置里,添加「Jacoco插件」的配置,指向测试项目target/site/jacoco目录下的报告文件,这样就能在Jenkins界面直接查看覆盖率统计了
常见坑点排查
  • 找不到业务类:检查业务项目是否生成了普通Jar,测试项目的依赖groupId、artifactId、version是否完全匹配,scope是否设为test(如果测试代码在编译阶段就需要依赖,改成compile)
  • Spring Bean无法注入:在测试类上添加@SpringBootTest(classes = 业务项目的启动类.class),确保Spring上下文能正确加载业务项目的所有Bean
  • Jacoco覆盖率为0:检查classesDirectory是否正确指向业务项目的target/classes目录,同时确认测试代码确实覆盖了业务类的方法(可以先跑单个测试看看有没有生效)

内容的提问来源于stack exchange,提问作者Maidi Gu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:54:48