Spock测试无法输出追踪信息的问题求助
解决Spock+Testcontainers测试中日志/追踪信息无法输出的问题
看起来你已经尝试了多种方式输出Testcontainers容器的追踪信息,但始终看不到预期内容。我来帮你一步步排查和解决这个问题:
1. 先搞定日志框架的基础配置
你用了SLF4J,但如果没有对应的日志绑定(比如Logback)或者配置文件,日志信息会被静默丢弃。请在test/resources目录下创建logback-test.xml文件,配置足够的日志级别:
<configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <!-- 开启你的测试类日志 --> <logger name="com.makobrothers.mako.rrhh.persona.infrastructure.controller.PersonaRestAssuredSpec" level="INFO"/> <!-- 开启Testcontainers核心日志,能看到容器创建/启动的详细过程 --> <logger name="org.testcontainers" level="DEBUG"/> <!-- 如果需要看Docker客户端的底层日志,也可以开启 --> <logger name="com.github.dockerjava" level="DEBUG"/> <root level="INFO"> <appender-ref ref="STDOUT"/> </root> </configuration>
2. 调整Gradle测试任务的日志配置
你的testLogging配置还不够完整,需要明确开启标准输出/错误的显示,以及日志内容的打印:
test { useJUnitPlatform() testLogging { events "PASSED", "SKIPPED", "FAILED", "STANDARD_OUT", "STANDARD_ERROR" // 强制显示标准输出和错误流的内容 showStandardStreams = true // 显示日志的级别和具体消息 showLog = true // 确保能捕捉到INFO及以上级别的日志 minGranularity = 2 } testClassesDirs = sourceSets.test.output classpath = sourceSets.test.runtimeClasspath reports { html.enabled = true } }
3. 确保Spock的Mixin扩展生效
你的SpockConfig.groovy必须放在test/resources目录下,Spock才会自动加载它。如果还是不行,直接在测试类上显式添加@Mixin注解更稳妥:
@Mixin(LabelPrinter) class PersonaRestAssuredSpec extends Specification { // ... 原有代码 }
4. 调整日志打印的时机
@Shared修饰的Testcontainers容器会在所有测试方法之前初始化,setup()方法里的打印可能已经错过了容器启动的关键阶段。可以改用setupSpec()方法(在所有测试执行前只跑一次),或者给容器添加日志消费者:
// 给容器添加日志消费者,直接输出容器的启动日志 public static PostgreSQLContainer staticPostgreSQL = new PostgreSQLContainer(POSTGRES_TEST_IMAGE) .withDatabaseName("makoTest") .withUsername("mako") .withPassword("mako") .withExposedPorts(5432) .withCreateContainerCmdModifier({ cmd -> cmd.withName('postgreSQL-' + ( RANDOM.nextInt() & Integer.MAX_VALUE )) }) .withLogConsumer(new Slf4jLogConsumer(log)) // 新增这一行,把容器日志转到SLF4J // 在setupSpec里打印初始化信息 def setupSpec() { log.info("容器已初始化,JDBC URL: ${postgreSQLContainer.jdbcUrl}") showTrace("容器名称: ${postgreSQLContainer.containerName}") }
5. 快速验证:用System.out直接打印
如果以上配置还是没效果,先在测试方法里加一行最基础的打印,确认输出通道是否正常:
def "showConfigTest"() { given: "A client request to test findById" System.out.println("=== 直接打印JDBC URL: " + postgreSQLContainer.getJdbcUrl()) // ... 原有代码 }
然后执行gradle clean test --info,用--info参数查看Gradle的详细日志,看看有没有被过滤的输出。
内容的提问来源于stack exchange,提问作者José-Alberto Gilberte León
相关产品推荐
相关产品推荐

