diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/OnFailureConditionReportContextCustomizerFactory.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/OnFailureConditionReportContextCustomizerFactory.java index d95ff503887a..987eada51589 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/OnFailureConditionReportContextCustomizerFactory.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/OnFailureConditionReportContextCustomizerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,7 +84,17 @@ private ApplicationFailureListener(Supplier reportSup @Override public void onApplicationEvent(ApplicationFailedEvent event) { - System.err.println(new ConditionEvaluationReportMessage(this.reportSupplier.get())); + if (shouldPrintReport(event.getApplicationContext())) { + System.err.println(new ConditionEvaluationReportMessage(this.reportSupplier.get())); + } + } + + private static boolean shouldPrintReport(ConfigurableApplicationContext context) { + if (context == null) { + return true; + } + return context.getEnvironment() + .getProperty("spring.test.print-condition-evaluation-report", Boolean.class, true); } } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-configuration-metadata.json b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-configuration-metadata.json index 32a5f8cfd477..3c9a69031616 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring-configuration-metadata.json @@ -17,6 +17,12 @@ "type": "java.lang.Boolean", "description": "Whether observability should be auto-configured in tests.", "defaultValue": "false" + }, + { + "name": "spring.test.print-condition-evaluation-report", + "type": "java.lang.Boolean", + "description": "Whether the condition evaluation report should be printed when the ApplicationContext fails to start.", + "defaultValue": "true" } ] } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OnFailureConditionReportContextCustomizerFactoryTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OnFailureConditionReportContextCustomizerFactoryTests.java index 87fc8ee8d85a..61ab000f5c26 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OnFailureConditionReportContextCustomizerFactoryTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OnFailureConditionReportContextCustomizerFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.boot.test.autoconfigure; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -24,9 +25,13 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; +import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.TestContextManager; +import org.springframework.test.context.cache.ContextCache; +import org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate; +import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; @@ -39,11 +44,42 @@ @ExtendWith(OutputCaptureExtension.class) class OnFailureConditionReportContextCustomizerFactoryTests { + @BeforeEach + void clearCache() { + ContextCache contextCache = (ContextCache) ReflectionTestUtils + .getField(DefaultCacheAwareContextLoaderDelegate.class, "defaultContextCache"); + if (contextCache != null) { + contextCache.reset(); + } + } + @Test void loadFailureShouldPrintReport(CapturedOutput output) { + load(); + assertThat(output.getErr()).contains("JacksonAutoConfiguration matched"); + assertThat(output).contains("Error creating bean with name 'faultyBean'"); + } + + @Test + @WithResource(name = "application.xml", content = "invalid xml") + void loadFailureShouldNotPrintReportWhenApplicationPropertiesIsBroken(CapturedOutput output) { + load(); + assertThat(output).doesNotContain("JacksonAutoConfiguration matched") + .doesNotContain("Error creating bean with name 'faultyBean'") + .contains("java.util.InvalidPropertiesFormatException"); + } + + @Test + @WithResource(name = "application.properties", content = "spring.test.print-condition-evaluation-report=false") + void loadFailureShouldNotPrintReportWhenDisabled(CapturedOutput output) { + load(); + assertThat(output).doesNotContain("JacksonAutoConfiguration matched") + .contains("Error creating bean with name 'faultyBean'"); + } + + private void load() { assertThatIllegalStateException() .isThrownBy(() -> new TestContextManager(FailingTests.class).getTestContext().getApplicationContext()); - assertThat(output).contains("JacksonAutoConfiguration matched"); } @SpringBootTest