Scala CLI执行测试后进程无法退出问题求助
Scala CLI执行测试后进程挂起问题排查
问题描述
- 执行命令
scala-cli test core时,测试已执行完成,但进程始终挂起无法退出,调试模式也无法定位原因 - 使用munit框架时问题偶发:同步测试可正常退出,部分异步测试挂起
- 切换至scalatest框架后问题必现:无论同步/异步测试,进程均无法退出
- 已简化测试为仅执行
assert(true),问题依旧存在
补充测试示例(Scalatest异步测试)
import org.scalatest.funspec.{AsyncFunSpec, AsyncFunSpecLike} import org.scalatest.funsuite.AsyncFunSuite class SlackAPITest extends AsyncFunSuite { implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global test("post message") { postMessage("whatever :chococat: :catbus: :catbus2:", testChannelId) } }
注:postMessage 方法返回 Future[String]
可能的解决方向
1. 避免使用全局ExecutionContext
全局ExecutionContext(scala.concurrent.ExecutionContext.global)依赖JVM的ForkJoinPool,测试完成后可能有后台线程未终止导致进程挂起。建议创建专用ExecutionContext,并在测试结束后手动关闭:
import org.scalatest.funsuite.AsyncFunSuite import org.scalatest.BeforeAndAfterAll import scala.concurrent.ExecutionContext import java.util.concurrent.Executors class SlackAPITest extends AsyncFunSuite with BeforeAndAfterAll { private val executor = Executors.newFixedThreadPool(4) implicit override val executionContext: ExecutionContext = ExecutionContext.fromExecutor(executor) override def afterAll(): Unit = { executor.shutdown() // 若使用外部客户端(如Slack API客户端),在此添加关闭逻辑 // client.close() } test("post message") { postMessage("whatever :chococat: :catbus: :catbus2:", testChannelId) } }
2. 检查依赖版本兼容性
确认Scala CLI与Scalatest的版本匹配:
- 升级Scala CLI至最新稳定版:执行
scala-cli self-update - 确保Scalatest版本适配当前Scala版本(如Scala 2.13/3.x对应Scalatest 3.2.+)
3. 排查未清理的资源
检查测试中是否存在未关闭的外部资源:
- HTTP客户端连接池(如Slack API客户端是否未关闭)
- 数据库连接、文件流等
这些资源的后台线程可能阻止进程退出,需在测试结束后手动释放。
4. 临时强制退出方案(不推荐长期使用)
若暂时无法定位根本原因,可在测试类中添加AfterAll钩子强制退出进程:
import org.scalatest.funsuite.AsyncFunSuite import org.scalatest.BeforeAndAfterAll class SlackAPITest extends AsyncFunSuite with BeforeAndAfterAll { implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global override def afterAll(): Unit = { System.exit(0) } test("post message") { postMessage("whatever :chococat: :catbus: :catbus2:", testChannelId) } }
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

