From 5c44c77287dfa1089b4ac7bf93282a484727a43f Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 6 Jul 2016 12:20:51 +0100 Subject: [PATCH] =?UTF-8?q?Document=20auto-configuration=20classes=20impor?= =?UTF-8?q?ted=20by=20each=20@=E2=80=A6Test=20annotation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes gh-6044 --- spring-boot-docs/pom.xml | 25 ++++ .../appendix-test-auto-configuration.adoc | 7 ++ .../src/main/asciidoc/appendix.adoc | 1 + .../main/asciidoc/spring-boot-features.adoc | 11 ++ .../groovy/generateTestSlicesTable.groovy | 109 ++++++++++++++++++ 5 files changed, 153 insertions(+) create mode 100644 spring-boot-docs/src/main/asciidoc/appendix-test-auto-configuration.adoc create mode 100644 spring-boot-docs/src/main/groovy/generateTestSlicesTable.groovy diff --git a/spring-boot-docs/pom.xml b/spring-boot-docs/pom.xml index 61f7721497..ff580e8181 100644 --- a/spring-boot-docs/pom.xml +++ b/spring-boot-docs/pom.xml @@ -886,6 +886,25 @@ + + unpack-test-slices + generate-resources + + unpack + + + + + org.springframework.boot + spring-boot-test-autoconfigure + ${project.version} + + ${project.build.directory}/test-auto-config + + + + + @@ -932,6 +951,7 @@ + @@ -940,6 +960,11 @@ groovy-all ${groovy.version} + + org.springframework + spring-core + ${spring.version} + diff --git a/spring-boot-docs/src/main/asciidoc/appendix-test-auto-configuration.adoc b/spring-boot-docs/src/main/asciidoc/appendix-test-auto-configuration.adoc new file mode 100644 index 0000000000..af7ba46d34 --- /dev/null +++ b/spring-boot-docs/src/main/asciidoc/appendix-test-auto-configuration.adoc @@ -0,0 +1,7 @@ +[appendix] +[[test-auto-configuration]] +== Test auto-configuration annotations +Here is a table of the various `@…Test` annotations that can be used to test +slices of your application and the auto-configuration that they import by default: + +include::../../../target/generated-resources/test-slice-auto-configuration.adoc[] \ No newline at end of file diff --git a/spring-boot-docs/src/main/asciidoc/appendix.adoc b/spring-boot-docs/src/main/asciidoc/appendix.adoc index 878ec6eb9d..4c32a668f6 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix.adoc @@ -4,5 +4,6 @@ include::appendix-application-properties.adoc[] include::appendix-configuration-metadata.adoc[] include::appendix-auto-configuration-classes.adoc[] +include::appendix-test-auto-configuration.adoc[] include::appendix-executable-jar-format.adoc[] include::appendix-dependency-versions.adoc[] diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 536ff3aa8a..db6f4e41c1 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -4879,6 +4879,9 @@ NOTE: JSON helper classes can also be used directly in standard unit tests. Simp call the `initFields` method of the helper in your `@Before` method if you aren't using `@JsonTest`. +A list of the auto-configuration that is enabled by `@JsonTest` can be +<>. + [[boot-features-testing-spring-boot-applications-testing-autoconfigured-mvc-tests]] @@ -4971,6 +4974,9 @@ and/or a `WebDriver` bean. Here is an example that uses HtmlUnit: } ---- +A list of the auto-configuration that is enabled by `@WebMvcTest` can be +<>. + [[boot-features-testing-spring-boot-applications-testing-autoconfigured-jpa-test]] @@ -5053,6 +5059,8 @@ database you can use the `@AutoConfigureTestDatabase` annotation: } ---- +A list of the auto-configuration that is enabled by `@DataJpaTest` can be +<>. @@ -5088,6 +5096,9 @@ be specified using `value` or `components` attribute of `@RestClientTest`: } ---- +A list of the auto-configuration that is enabled by `@RestClientTest` can be +<>. + [[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs]] diff --git a/spring-boot-docs/src/main/groovy/generateTestSlicesTable.groovy b/spring-boot-docs/src/main/groovy/generateTestSlicesTable.groovy new file mode 100644 index 0000000000..3b3928dabd --- /dev/null +++ b/spring-boot-docs/src/main/groovy/generateTestSlicesTable.groovy @@ -0,0 +1,109 @@ +import groovy.io.FileType + +import java.util.Properties + +import org.springframework.core.io.InputStreamResource +import org.springframework.core.io.Resource +import org.springframework.core.type.AnnotationMetadata +import org.springframework.core.type.ClassMetadata +import org.springframework.core.type.classreading.MetadataReader +import org.springframework.core.type.classreading.MetadataReaderFactory +import org.springframework.core.type.classreading.SimpleMetadataReaderFactory +import org.springframework.util.ClassUtils +import org.springframework.util.StringUtils + +class Project { + + final List classFiles + + final Properties springFactories + + Project(File rootDirectory) { + this.springFactories = loadSpringFactories(rootDirectory) + this.classFiles = [] + rootDirectory.eachFileRecurse (FileType.FILES) { file -> + if (file.name.endsWith('.class')) { + classFiles << file + } + } + } + + private static Properties loadSpringFactories(File rootDirectory) { + Properties springFactories = new Properties() + new File(rootDirectory, 'META-INF/spring.factories').withInputStream { inputStream -> + springFactories.load(inputStream) + } + return springFactories + } +} + +class TestSlice { + + final String name + + final SortedSet importedAutoConfiguration + + TestSlice(String annotationName, Collection importedAutoConfiguration) { + this.name = ClassUtils.getShortName(annotationName) + this.importedAutoConfiguration = new TreeSet(importedAutoConfiguration) + } +} + +List createTestSlices(Project project) { + MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory() + project.classFiles + .findAll { classFile -> + classFile.name.endsWith('Test.class') + }.collect { classFile -> + createMetadataReader(metadataReaderFactory, classFile) + }.findAll { metadataReader -> + metadataReader.classMetadata.annotation + }.collect { metadataReader -> + createTestSlice(project.springFactories, metadataReader.classMetadata, metadataReader.annotationMetadata) + }.sort { + a, b -> a.name.compareTo b.name + } +} + +MetadataReader createMetadataReader(MetadataReaderFactory factory, File classFile) { + classFile.withInputStream { inputStream -> + factory.getMetadataReader(new InputStreamResource(inputStream)) + } +} + +TestSlice createTestSlice(Properties springFactories, ClassMetadata classMetadata, AnnotationMetadata annotationMetadata) { + new TestSlice(classMetadata.className, getImportedAutoConfiguration(springFactories, classMetadata, annotationMetadata)) +} + +Set getImportedAutoConfiguration(Properties springFactories, ClassMetadata classMetadata, AnnotationMetadata annotationMetadata) { + annotationMetadata.annotationTypes + .findAll { annotationType -> + isAutoConfigurationImporter(annotationType, annotationMetadata) + }.collect { autoConfigurationImporter -> + StringUtils.commaDelimitedListToSet(springFactories.get(autoConfigurationImporter)) + }.flatten() +} + +boolean isAutoConfigurationImporter(String annotationType, AnnotationMetadata metadata) { + metadata.getMetaAnnotationTypes(annotationType).contains('org.springframework.boot.autoconfigure.ImportAutoConfiguration') +} + +void writeTestSlicesTable(List testSlices) { + new File(project.build.directory, "generated-resources/test-slice-auto-configuration.adoc").withPrintWriter { writer -> + writer.println '[cols="d,a"]' + writer.println '|===' + writer.println '| Test slice | Imported auto-configuration' + testSlices.each { testSlice -> + writer.println '' + writer.println "| `@${testSlice.name}`" + writer.print '| ' + testSlice.importedAutoConfiguration.each { + writer.println "`${it}`" + } + } + writer.println '|===' + } +} + +List testSlices = createTestSlices(new Project(new File(project.build.directory, 'test-auto-config'))) +writeTestSlicesTable(testSlices)