From 5890d0b8a51e2e9353da327fa8901e56d823a00d Mon Sep 17 00:00:00 2001
From: Dmytro Nosan <dimanosan@gmail.com>
Date: Wed, 9 Apr 2025 18:48:59 +0300
Subject: [PATCH] Introduce 'spring.test.print-condition-evaluation-report'
 property

Add the `spring.test.print-condition-evaluation-report` property
to enable or disable the conditional evaluation report
when ApplicationContext fails to start.

Signed-off-by: Dmytro Nosan <dimanosan@gmail.com>
---
 ...nditionReportContextCustomizerFactory.java | 14 ++++++-
 .../spring-configuration-metadata.json        |  6 +++
 ...onReportContextCustomizerFactoryTests.java | 40 ++++++++++++++++++-
 3 files changed, 56 insertions(+), 4 deletions(-)

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<ConditionEvaluationReport> 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