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

GitLab CI中Gradle构建Kotlin库test任务挂起问题求助

问题根源分析

从你补充的信息来看,问题的核心是测试中启动的后台线程没有被正确终止。本地测试时,可能因为IDE的进程管理特性(比如测试结束后自动销毁JVM进程),即使有非守护线程未关闭,也不会出现挂起;但GitLab CI的环境是严格遵循JVM退出规则的——只有当所有非守护线程都终止后,JVM才会退出,Gradle的test任务才会结束。当你运行两个及以上测试用例时,多个未终止的线程积累,导致JVM无法退出,任务就卡在Task :test状态。

解决方案

针对这个问题,有两种可靠的解决思路:

1. 手动清理测试资源(推荐)

在每个测试用例执行完成后,显式停止Controller的后台线程,确保资源被正确释放:

import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Test

class YourControllerTest {
    private lateinit var controller: YourController

    @Test
    fun testControllerStart() {
        controller = YourController()
        controller.start()
        // 测试逻辑
    }

    @AfterEach
    fun tearDown() {
        // 调用Controller的停止方法,确保后台线程终止
        controller.stop()
    }
}

如果你的Controller没有提供stop()方法,需要实现线程终止逻辑——比如用interrupt()中断线程,或者用一个标志位让线程自行退出循环。

2. 将后台线程设置为守护线程

如果这些后台线程不需要执行收尾操作,也不影响测试结果的正确性,可以将线程设置为守护线程:

class YourController {
    fun start() {
        val backgroundThread = Thread {
            // 线程逻辑
        }
        backgroundThread.isDaemon = true // 设置为守护线程
        backgroundThread.start()
    }
}

守护线程的特点是:当JVM中所有非守护线程都终止时,JVM会直接退出,不会等待守护线程完成。这种方式适合不需要优雅关闭的后台任务。

Kotlin + Gradle + GitLab CI 标准模板

这里提供一个经过实践验证的标准配置模板,适配大多数Kotlin库项目:

image: gradle:7.6-jdk11 # 推荐使用较新的Gradle和JDK版本,兼容性更好
stages:
  - build
  - test
  - deploy # 可选,根据项目需求添加

before_script:
  - export GRADLE_USER_HOME=$(pwd)/.gradle
  - chmod +x ./gradlew # 确保Gradle Wrapper脚本有执行权限

cache:
  paths:
    - .gradle/wrapper
    - .gradle/caches
    - build/libs/ # 可选,缓存构建产物加快后续构建

build:
  stage: build
  script:
    - ./gradlew assemble
  artifacts:
    paths:
      - build/libs/*.jar
    expire_in: 1 week
  only:
    - master
    - tags
    - merge_requests # 合并请求阶段也触发构建,提前发现问题

test:
  stage: test
  script:
    - ./gradlew check
  artifacts:
    reports:
      junit: build/test-results/test/**/*.xml # 让GitLab展示测试报告详情
    expire_in: 1 week
  only:
    - master
    - tags
    - merge_requests

# 可选的部署任务示例
deploy-to-repo:
  stage: deploy
  script:
    - ./gradlew publish
  only:
    - tags # 仅在打标签时触发部署

模板关键点说明:

  • 使用较新的Gradle镜像:避免旧版本的兼容性问题,同时支持Kotlin的新特性
  • 添加chmod +x ./gradlew:解决Git克隆后脚本无执行权限的常见问题
  • 配置测试报告 artifacts:GitLab会自动解析JUnit格式的测试报告,展示通过率、失败用例等信息
  • 合并请求触发构建:在代码合并前提前验证构建和测试是否通过
  • 缓存优化:减少重复下载依赖和构建的时间,提升CI效率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:12:51