From 39bc3cb82c3c6ffaf33a686e9546a5f42d6fa9b0 Mon Sep 17 00:00:00 2001 From: Maciej Kucharczyk Date: Tue, 13 Aug 2024 16:35:16 +0200 Subject: [PATCH 1/3] Abstraction for reading test metadata added --- .../DefaultXrayTestMetadataReader.java | 98 ++++++ ...ncedLegacyXmlReportGeneratingListener.java | 9 +- .../junit/customjunitxml/XmlReportWriter.java | 76 ++--- .../XrayTestMetadataReader.java | 50 +++ .../CustomXrayTestMetadataReader.java | 62 ++++ .../DefaultXrayTestInfoReaderTest.java | 321 ++++++++++++++++++ .../customjunitxml/EnhancedLegacyXmlTest.java | 36 ++ .../customjunitxml/data/MockedTestClass.java | 58 ++++ ...ckedTestWithDisplayNameGeneratorClass.java | 46 +++ 9 files changed, 704 insertions(+), 52 deletions(-) create mode 100644 src/main/java/app/getxray/xray/junit/customjunitxml/DefaultXrayTestMetadataReader.java create mode 100644 src/main/java/app/getxray/xray/junit/customjunitxml/XrayTestMetadataReader.java create mode 100644 src/test/java/app/getxray/xray/junit/customjunitxml/CustomXrayTestMetadataReader.java create mode 100644 src/test/java/app/getxray/xray/junit/customjunitxml/DefaultXrayTestInfoReaderTest.java create mode 100644 src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestClass.java create mode 100644 src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestWithDisplayNameGeneratorClass.java diff --git a/src/main/java/app/getxray/xray/junit/customjunitxml/DefaultXrayTestMetadataReader.java b/src/main/java/app/getxray/xray/junit/customjunitxml/DefaultXrayTestMetadataReader.java new file mode 100644 index 0000000..e744c42 --- /dev/null +++ b/src/main/java/app/getxray/xray/junit/customjunitxml/DefaultXrayTestMetadataReader.java @@ -0,0 +1,98 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * https://www.eclipse.org/legal/epl-v20.html + */ + +package app.getxray.xray.junit.customjunitxml; + +import app.getxray.xray.junit.customjunitxml.annotations.Requirement; +import app.getxray.xray.junit.customjunitxml.annotations.XrayTest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.TestFactory; +import org.junit.platform.commons.support.AnnotationSupport; +import org.junit.platform.engine.support.descriptor.MethodSource; +import org.junit.platform.launcher.TestIdentifier; + +import java.lang.annotation.Annotation; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +public class DefaultXrayTestMetadataReader implements XrayTestMetadataReader { + + @Override + public Optional getId(TestIdentifier testIdentifier) { + return getTestMethodAnnotation(testIdentifier, XrayTest.class) + .map(XrayTest::id) + .filter(s -> !s.isEmpty()); + } + + @Override + public Optional getKey(TestIdentifier testIdentifier) { + return getTestMethodAnnotation(testIdentifier, XrayTest.class) + .map(XrayTest::key) + .filter(s -> !s.isEmpty()); + } + + @Override + public Optional getSummary(TestIdentifier testIdentifier) { + Optional testSummary = getTestMethodAnnotation(testIdentifier, XrayTest.class) + .map(XrayTest::summary) + .filter(s -> !s.isEmpty()); + if (testSummary.isPresent()) { + return testSummary; + } + + Optional displayName = getTestMethodAnnotation(testIdentifier, DisplayName.class); + if (displayName.isPresent()) { + return Optional.of(displayName.get().value()); + } + + + Optional dynamicTest = getTestMethodAnnotation(testIdentifier, TestFactory.class); + Optional displayNameGenerator = getTestClassAnnotation(testIdentifier, DisplayNameGeneration.class); + if (dynamicTest.isPresent() || displayNameGenerator.isPresent()) { + return Optional.of(testIdentifier.getDisplayName()); + } + + return Optional.empty(); + } + + @Override + public Optional getDescription(TestIdentifier testIdentifier) { + return getTestMethodAnnotation(testIdentifier, XrayTest.class) + .map(XrayTest::description) + .filter(s -> !s.isEmpty()); + } + + @Override + public List getRequirements(TestIdentifier testIdentifier) { + return getTestMethodAnnotation(testIdentifier, Requirement.class) + .map(Requirement::value) + .map(arr -> Collections.unmodifiableList(Arrays.asList(arr))) + .orElse(Collections.emptyList()); + } + + protected Optional getTestMethodAnnotation(TestIdentifier testIdentifier, Class aClass) { + return testIdentifier.getSource() + .filter(a -> a instanceof MethodSource) + .map(MethodSource.class::cast) + .map(MethodSource::getJavaMethod) + .flatMap(a -> AnnotationSupport.findAnnotation(a, aClass)); + } + + protected Optional getTestClassAnnotation(TestIdentifier testIdentifier, Class aClass) { + return testIdentifier.getSource() + .filter(a -> a instanceof MethodSource) + .map(MethodSource.class::cast) + .map(MethodSource::getJavaClass) + .flatMap(a -> AnnotationSupport.findAnnotation(a, aClass)); + } +} diff --git a/src/main/java/app/getxray/xray/junit/customjunitxml/EnhancedLegacyXmlReportGeneratingListener.java b/src/main/java/app/getxray/xray/junit/customjunitxml/EnhancedLegacyXmlReportGeneratingListener.java index 461905c..ce88dc7 100644 --- a/src/main/java/app/getxray/xray/junit/customjunitxml/EnhancedLegacyXmlReportGeneratingListener.java +++ b/src/main/java/app/getxray/xray/junit/customjunitxml/EnhancedLegacyXmlReportGeneratingListener.java @@ -21,9 +21,6 @@ import javax.xml.stream.XMLStreamException; -import static org.junit.jupiter.api.DynamicTest.stream; - -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; @@ -65,6 +62,7 @@ public class EnhancedLegacyXmlReportGeneratingListener implements TestExecutionL boolean addTimestampToReportFilename = false; boolean reportOnlyAnnotatedTests = false; boolean reportsPerClass = false; + XrayTestMetadataReader testInfoReader = new DefaultXrayTestMetadataReader(); private XmlReportData reportData; @@ -95,6 +93,9 @@ public EnhancedLegacyXmlReportGeneratingListener(Path reportsDir, Path propertie this.addTimestampToReportFilename = "true".equals(properties.getProperty("add_timestamp_to_report_filename")); this.reportOnlyAnnotatedTests = "true".equals(properties.getProperty("report_only_annotated_tests", "false")); this.reportsPerClass = "true".equals(properties.getProperty("reports_per_class", "false")); + if (!properties.getProperty("test_metadata_reader").isEmpty()) { + this.testInfoReader = (XrayTestMetadataReader) Class.forName(properties.getProperty("test_metadata_reader")).getConstructor().newInstance(); + } } else { if (reportsDir == null) { this.reportsDir = FileSystems.getDefault().getPath(DEFAULT_REPORTS_DIR); @@ -183,7 +184,7 @@ private void writeXmlReportSafely(TestIdentifier testIdentifier, String rootName xmlFile = this.reportsDir.resolve(fileName); try (Writer fileWriter = Files.newBufferedWriter(xmlFile)) { - new XmlReportWriter(this.reportData, this.reportOnlyAnnotatedTests).writeXmlReport(testIdentifier, fileWriter); + new XmlReportWriter(this.reportData, this.reportOnlyAnnotatedTests, this.testInfoReader).writeXmlReport(testIdentifier, fileWriter); } catch (XMLStreamException | IOException e) { printException("Could not write XML report: " + xmlFile, e); logger.error(e, () -> "Could not write XML report: " + xmlFile); diff --git a/src/main/java/app/getxray/xray/junit/customjunitxml/XmlReportWriter.java b/src/main/java/app/getxray/xray/junit/customjunitxml/XmlReportWriter.java index f91bc54..f949080 100644 --- a/src/main/java/app/getxray/xray/junit/customjunitxml/XmlReportWriter.java +++ b/src/main/java/app/getxray/xray/junit/customjunitxml/XmlReportWriter.java @@ -10,9 +10,6 @@ package app.getxray.xray.junit.customjunitxml; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.DisplayNameGeneration; -import org.junit.jupiter.api.TestFactory; import org.junit.platform.commons.logging.Logger; import org.junit.platform.commons.logging.LoggerFactory; import org.junit.platform.commons.support.AnnotationSupport; @@ -96,14 +93,19 @@ class XmlReportWriter { // re-add separator characters. private static final Pattern CDATA_SPLIT_PATTERN = Pattern.compile("(?<=]])(?=>)"); - private final XmlReportData reportData; - private static final Logger logger = LoggerFactory.getLogger(EnhancedLegacyXmlReportGeneratingListener.class); - private boolean reportOnlyAnnotatedTests = false; + private static final Logger logger = LoggerFactory.getLogger(EnhancedLegacyXmlReportGeneratingListener.class); - XmlReportWriter(XmlReportData reportData, boolean reportOnlyAnnotatedTests) { - this.reportData = reportData; + private final XmlReportData reportData; + private final boolean reportOnlyAnnotatedTests; + private final XrayTestMetadataReader xrayTestMetadataReader; + + XmlReportWriter(XmlReportData reportData, + boolean reportOnlyAnnotatedTests, + XrayTestMetadataReader xrayTestMetadataReader) { + this.reportData = reportData; this.reportOnlyAnnotatedTests = reportOnlyAnnotatedTests; - } + this.xrayTestMetadataReader = xrayTestMetadataReader; + } void writeXmlReport(TestIdentifier rootDescriptor, Writer out) throws XMLStreamException { TestPlan testPlan = this.reportData.getTestPlan(); @@ -234,7 +236,6 @@ private void writeTestcase(TestIdentifier testIdentifier, AggregatedTestResult t final Optional testSource = testIdentifier.getSource(); final Optional testMethod = testSource.flatMap(this::getTestMethod); - final Class testClass = ((MethodSource)testSource.get()).getJavaClass(); Optional xrayTest = AnnotationSupport.findAnnotation(testMethod, XrayTest.class); Optional requirement = AnnotationSupport.findAnnotation(testMethod, Requirement.class); if (reportOnlyAnnotatedTests && (!requirement.isPresent() && !xrayTest.isPresent())) { @@ -272,49 +273,28 @@ private void writeTestcase(TestIdentifier testIdentifier, AggregatedTestResult t newLine(writer); } - // final Optional> testClass = testSource.flatMap(this::getTestClass); - - if (requirement.isPresent()) { - String[] requirements = requirement.get().value(); + List requirements = xrayTestMetadataReader.getRequirements(testIdentifier); + if (!requirements.isEmpty()) { addProperty(writer, "requirements", String.join(",", requirements)); } - String test_key = null; - String test_id = null; - String test_summary = null; - String test_description = null; - if (xrayTest.isPresent()) { - test_key = xrayTest.get().key(); - if ((test_key != null) && (!test_key.isEmpty())) { - addProperty(writer, "test_key", test_key); - } - - test_id = xrayTest.get().id(); - if ((test_id != null) && (!test_id.isEmpty())) { - addProperty(writer, "test_id", test_id); - } - - test_summary = xrayTest.get().summary(); - test_description = xrayTest.get().description(); - if ((test_description != null) && (!test_description.isEmpty())) { - addPropertyWithInnerContent(writer, "test_description", test_description); - } - } - - Optional dynamicTest = AnnotationSupport.findAnnotation(testMethod, TestFactory.class); - Optional displayName = AnnotationSupport.findAnnotation(testMethod, DisplayName.class); - Optional displayNameGenerator = AnnotationSupport.findAnnotation(testClass, DisplayNameGeneration.class); + Optional test_key = xrayTestMetadataReader.getKey(testIdentifier); + if (test_key.isPresent()) { + addProperty(writer, "test_key", test_key.get()); + } + Optional test_id = xrayTestMetadataReader.getId(testIdentifier); + if (test_id.isPresent()) { + addProperty(writer, "test_id", test_id.get()); + } - // this logic should be improved/simplified; the displayNameGererator logic isnt handling all cases, inclusing if it was set globally - if ( ((test_summary == null) || (test_summary.isEmpty())) && (displayName.isPresent()) ) { - test_summary = displayName.get().value(); - } - if ( ((test_summary == null) || (test_summary.isEmpty())) && (dynamicTest.isPresent() || displayNameGenerator.isPresent()) ) { - test_summary = testIdentifier.getDisplayName(); - } + Optional test_description = xrayTestMetadataReader.getDescription(testIdentifier); + if (test_description.isPresent()) { + addPropertyWithInnerContent(writer, "test_description", test_description.get()); + } - if ((test_summary != null) && (!test_summary.isEmpty())) { - addProperty(writer, "test_summary", test_summary); + Optional test_summary = xrayTestMetadataReader.getSummary(testIdentifier); + if (test_summary.isPresent()) { + addProperty(writer, "test_summary", test_summary.get()); } List tags = testIdentifier.getTags().stream().map(TestTag::getName).map(String::trim) diff --git a/src/main/java/app/getxray/xray/junit/customjunitxml/XrayTestMetadataReader.java b/src/main/java/app/getxray/xray/junit/customjunitxml/XrayTestMetadataReader.java new file mode 100644 index 0000000..3803a28 --- /dev/null +++ b/src/main/java/app/getxray/xray/junit/customjunitxml/XrayTestMetadataReader.java @@ -0,0 +1,50 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * https://www.eclipse.org/legal/epl-v20.html + */ + +package app.getxray.xray.junit.customjunitxml; + +import org.junit.platform.launcher.TestIdentifier; + +import java.util.List; +import java.util.Optional; + +public interface XrayTestMetadataReader { + + /** + * @param testIdentifier test identifier + * @return test id if any or empty + */ + Optional getId(TestIdentifier testIdentifier); + + /** + * @param testIdentifier test identifier + * @return test key if any + */ + Optional getKey(TestIdentifier testIdentifier); + + /** + * @param testIdentifier test identifier + * @return test summary if any + */ + Optional getSummary(TestIdentifier testIdentifier); + + /** + * @param testIdentifier test identifier + * @return test description if any + */ + Optional getDescription(TestIdentifier testIdentifier); + + /** + * @param testIdentifier test identifier + * @return Unmodifiable list of requirements + */ + List getRequirements(TestIdentifier testIdentifier); + +} diff --git a/src/test/java/app/getxray/xray/junit/customjunitxml/CustomXrayTestMetadataReader.java b/src/test/java/app/getxray/xray/junit/customjunitxml/CustomXrayTestMetadataReader.java new file mode 100644 index 0000000..85e7524 --- /dev/null +++ b/src/test/java/app/getxray/xray/junit/customjunitxml/CustomXrayTestMetadataReader.java @@ -0,0 +1,62 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * https://www.eclipse.org/legal/epl-v20.html + */ + +package app.getxray.xray.junit.customjunitxml; + +import org.junit.platform.engine.support.descriptor.MethodSource; +import org.junit.platform.launcher.TestIdentifier; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +public class CustomXrayTestMetadataReader implements XrayTestMetadataReader { + @Override + public Optional getId(TestIdentifier testIdentifier) { + return testIdentifier.getSource() + .map(MethodSource.class::cast) + .map(MethodSource::getJavaMethod) + .map(Method::getName) + .map(a -> "ID:" + a); + } + + @Override + public Optional getKey(TestIdentifier testIdentifier) { + return testIdentifier.getSource() + .map(MethodSource.class::cast) + .map(MethodSource::getJavaMethod) + .map(Method::getName) + .map(a -> "KEY:" + a); + } + + @Override + public Optional getSummary(TestIdentifier testIdentifier) { + return testIdentifier.getSource() + .map(MethodSource.class::cast) + .map(MethodSource::getJavaMethod) + .map(Method::getName) + .map(a -> "SUMMARY:" + a); + } + + @Override + public Optional getDescription(TestIdentifier testIdentifier) { + return testIdentifier.getSource() + .map(MethodSource.class::cast) + .map(MethodSource::getJavaMethod) + .map(Method::getName) + .map(a -> "DESCRIPTION:" + a); + } + + @Override + public List getRequirements(TestIdentifier testIdentifier) { + return Collections.emptyList(); + } +} diff --git a/src/test/java/app/getxray/xray/junit/customjunitxml/DefaultXrayTestInfoReaderTest.java b/src/test/java/app/getxray/xray/junit/customjunitxml/DefaultXrayTestInfoReaderTest.java new file mode 100644 index 0000000..8a19af7 --- /dev/null +++ b/src/test/java/app/getxray/xray/junit/customjunitxml/DefaultXrayTestInfoReaderTest.java @@ -0,0 +1,321 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * https://www.eclipse.org/legal/epl-v20.html + */ + +package app.getxray.xray.junit.customjunitxml; + +import app.getxray.xray.junit.customjunitxml.data.MockedTestClass; +import app.getxray.xray.junit.customjunitxml.data.MockedTestWithDisplayNameGeneratorClass; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.engine.config.DefaultJupiterConfiguration; +import org.junit.jupiter.engine.config.JupiterConfiguration; +import org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor; +import org.junit.platform.engine.ConfigurationParameters; +import org.junit.platform.engine.TestDescriptor; +import org.junit.platform.engine.UniqueId; +import org.junit.platform.launcher.TestIdentifier; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +class DefaultXrayTestInfoReaderTest { + + private final XrayTestMetadataReader xrayTestMetadataReader = new DefaultXrayTestMetadataReader(); + private static TestDescriptor XRAYTEST_ANNOTATED; + private static TestDescriptor XRAYTEST_EMPTY_ANNOTATION; + private static TestDescriptor NOT_ANNOTATED; + private static TestDescriptor DISPLAY_NAME_ANNOTATED; + private static TestDescriptor XRAYTEST_AND_DISPLAY_NAME_ANNOTATED; + private static TestDescriptor WITH_DISPLAY_NAME_GENERATOR; + private static TestDescriptor WITH_TEST_FACTORY; + + @BeforeAll + static void setUp() throws NoSuchMethodException { + JupiterConfiguration jupiterConfiguration = new DefaultJupiterConfiguration( + new ConfigurationParameters() { + @Override + public Optional get(String key) { + return Optional.empty(); + } + + @Override + public Optional getBoolean(String key) { + return Optional.empty(); + } + + @Override + public int size() { + return 0; + } + + @Override + public Set keySet() { + return Collections.emptySet(); + } + } + ); + + XRAYTEST_ANNOTATED = new TestMethodTestDescriptor( + UniqueId.forEngine("foo"), + MockedTestClass.class, + MockedTestClass.class.getMethod("annotatedWithValues"), + jupiterConfiguration + ); + XRAYTEST_EMPTY_ANNOTATION = new TestMethodTestDescriptor( + UniqueId.forEngine("foo"), + MockedTestClass.class, + MockedTestClass.class.getMethod("annotatedWithEmptyValues"), + jupiterConfiguration + ); + NOT_ANNOTATED = new TestMethodTestDescriptor( + UniqueId.forEngine("foo"), + MockedTestClass.class, + MockedTestClass.class.getMethod("notAnnotatedTest"), + jupiterConfiguration + ); + DISPLAY_NAME_ANNOTATED = new TestMethodTestDescriptor( + UniqueId.forEngine("foo"), + MockedTestClass.class, + MockedTestClass.class.getMethod("annotatedWithDisplayName"), + jupiterConfiguration + ); + XRAYTEST_AND_DISPLAY_NAME_ANNOTATED = new TestMethodTestDescriptor( + UniqueId.forEngine("foo"), + MockedTestClass.class, + MockedTestClass.class.getMethod("annotatedWithXrayTestAndDisplayName"), + jupiterConfiguration + ); + WITH_DISPLAY_NAME_GENERATOR = new TestMethodTestDescriptor( + UniqueId.forEngine("foo"), + MockedTestWithDisplayNameGeneratorClass.class, + MockedTestWithDisplayNameGeneratorClass.class.getMethod("withDisplayNameGenerator"), + jupiterConfiguration + ); + WITH_TEST_FACTORY = new TestMethodTestDescriptor( + UniqueId.forEngine("foo"), + MockedTestClass.class, + MockedTestClass.class.getMethod("withTestFactory"), + jupiterConfiguration + ); + } + + @Test + void shouldReturnKeyFromXrayTestAnnotation() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_ANNOTATED); + // WHEN + Optional keyOpt = xrayTestMetadataReader.getKey(testIdentifier); + // THEN + assertThat(keyOpt) + .contains("ABC-123"); + } + + @Test + void shouldReturnOptionalEmptyFromXrayTestAnnotationWithEmptyKey() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_EMPTY_ANNOTATION); + // WHEN + Optional keyOpt = xrayTestMetadataReader.getKey(testIdentifier); + // THEN + assertThat(keyOpt) + .isEmpty(); + } + + @Test + void shouldReturnOptionalEmptyKeyWhenMethodNotAnnotated() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(NOT_ANNOTATED); + // WHEN + Optional keyOpt = xrayTestMetadataReader.getKey(testIdentifier); + // THEN + assertThat(keyOpt) + .isEmpty(); + } + + @Test + void shouldReturnIdFromXrayTestAnnotation() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_ANNOTATED); + // WHEN + Optional idOpt = xrayTestMetadataReader.getId(testIdentifier); + // THEN + assertThat(idOpt) + .contains("868"); + } + + @Test + void shouldReturnOptionalEmptyFromXrayTestAnnotationWithEmptyId() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_EMPTY_ANNOTATION); + // WHEN + Optional idOpt = xrayTestMetadataReader.getId(testIdentifier); + // THEN + assertThat(idOpt) + .isEmpty(); + } + + @Test + void shouldReturnOptionalEmptyIdWhenMethodNotAnnotated() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(NOT_ANNOTATED); + // WHEN + Optional idOpt = xrayTestMetadataReader.getId(testIdentifier); + // THEN + assertThat(idOpt) + .isEmpty(); + } + + @Test + void shouldReturnSummaryFromXrayTestAnnotation() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_ANNOTATED); + // WHEN + Optional summaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); + // THEN + assertThat(summaryOpt) + .contains("some summary"); + } + + @Test + void shouldReturnOptionalEmptyFromXrayTestAnnotationWithEmptySummary() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_EMPTY_ANNOTATION); + // WHEN + Optional summaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); + // THEN + assertThat(summaryOpt) + .isEmpty(); + } + + @Test + void shouldReturnOptionalEmptySummaryWhenMethodNotAnnotated() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(NOT_ANNOTATED); + // WHEN + Optional summaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); + // THEN + assertThat(summaryOpt) + .isEmpty(); + } + + @Test + void shouldReturnDisplayNameWhenNotAnnotatedWithXrayTest() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(DISPLAY_NAME_ANNOTATED); + // WHEN + Optional summaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); + // THEN + assertThat(summaryOpt) + .contains("display name"); + } + + @Test + void shouldReturnDisplayNameFromXrayTestAnnotationWhenAlsoAnnotatedWithDisplayName() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_AND_DISPLAY_NAME_ANNOTATED); + // WHEN + Optional summaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); + // THEN + assertThat(summaryOpt) + .contains("xray summary"); + } + + @Test + void shouldReturnDefaultDisplayNameWhenAnnotatedWithDisplayNameGenerator() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(WITH_DISPLAY_NAME_GENERATOR); + // WHEN + Optional summaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); + // THEN + assertThat(summaryOpt) + .contains("DisplayNameForMethod"); + } + + @Test + void shouldReturnDefaultDisplayNameWhenAnnotatedWithTestFactory() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(WITH_TEST_FACTORY); + // WHEN + Optional summaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); + // THEN + assertThat(summaryOpt) + .contains("withTestFactory()"); + } + + @Test + void shouldReturnDescriptionFromXrayTestAnnotation() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_ANNOTATED); + // WHEN + Optional descriptionOpt = xrayTestMetadataReader.getDescription(testIdentifier); + // THEN + assertThat(descriptionOpt) + .contains("some description"); + } + + @Test + void shouldReturnOptionalEmptyFromXrayTestAnnotationWithEmptyDescription() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_EMPTY_ANNOTATION); + // WHEN + Optional descriptionOpt = xrayTestMetadataReader.getDescription(testIdentifier); + // THEN + assertThat(descriptionOpt) + .isEmpty(); + } + + @Test + void shouldReturnOptionalEmptyDescriptionWhenMethodNotAnnotated() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(NOT_ANNOTATED); + // WHEN + Optional descriptionOpt = xrayTestMetadataReader.getDescription(testIdentifier); + // THEN + assertThat(descriptionOpt) + .isEmpty(); + } + + @Test + void shouldReturnRequirementsFromRequirementsAnnotation() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_ANNOTATED); + // WHEN + List requirements = xrayTestMetadataReader.getRequirements(testIdentifier); + // THEN + assertThat(requirements) + .containsExactly("REQ-1", "REQ-2"); + } + + @Test + void shouldReturnEmptyListFromRequirementsAnnotationWithEmptyArray() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_EMPTY_ANNOTATION); + // WHEN + List requirements = xrayTestMetadataReader.getRequirements(testIdentifier); + // THEN + assertThat(requirements) + .isEmpty(); + } + + @Test + void shouldReturnEmptyListOfRequirementsWhenMethodNotAnnotated() { + // GIVEN + TestIdentifier testIdentifier = TestIdentifier.from(NOT_ANNOTATED); + // WHEN + List requirements = xrayTestMetadataReader.getRequirements(testIdentifier); + // THEN + assertThat(requirements) + .isEmpty(); + } +} \ No newline at end of file diff --git a/src/test/java/app/getxray/xray/junit/customjunitxml/EnhancedLegacyXmlTest.java b/src/test/java/app/getxray/xray/junit/customjunitxml/EnhancedLegacyXmlTest.java index e27cd44..ed84216 100644 --- a/src/test/java/app/getxray/xray/junit/customjunitxml/EnhancedLegacyXmlTest.java +++ b/src/test/java/app/getxray/xray/junit/customjunitxml/EnhancedLegacyXmlTest.java @@ -104,6 +104,42 @@ public void shouldReportPerTestClass() throws Exception { assertThat(testsuite.children("testcase").matchAttr("name", "anotherSimpleTest")).isNotEmpty(); } + @Test + public void shouldUseCustomMetadataReader() throws Exception { + String customProperties = "test_metadata_reader=" + CustomXrayTestMetadataReader.class.getName() + "\n"; + Path customPropertiesFile = Files.createTempFile("xray-junit-extensions", ".properties"); + Files.write(customPropertiesFile, customProperties.getBytes()); + + executeTestClasses(new Class[]{BASIC_CLASS}, customPropertiesFile, Clock.systemDefaultZone()); + + String reportName = "TEST-junit-jupiter.xml"; + Match testsuite = readValidXmlFile(tempDirectory.resolve(reportName)); + assertThat(testsuite.children("testcase")).hasSize(2); + + Match someBasicTestTestCase = testsuite.children("testcase").matchAttr("name", "someBasicTest"); + assertThat(someBasicTestTestCase).isNotEmpty(); + Match someBasicTestTestCaseProps = someBasicTestTestCase.children("properties").children("property"); + assertThat(someBasicTestTestCaseProps.matchAttr("name", "test_id").attr("value")) + .isEqualTo("ID:someBasicTest"); + assertThat(someBasicTestTestCaseProps.matchAttr("name", "test_key").attr("value")) + .isEqualTo("KEY:someBasicTest"); + assertThat(someBasicTestTestCaseProps.matchAttr("name", "test_summary").attr("value")) + .isEqualTo("SUMMARY:someBasicTest"); + assertThat(someBasicTestTestCaseProps.matchAttr("name", "test_description").text()) + .isEqualTo("DESCRIPTION:someBasicTest"); + + Match anotherBasicTestTestCase = testsuite.children("testcase").matchAttr("name", "anotherBasicTest"); + assertThat(anotherBasicTestTestCase).isNotEmpty(); + Match anotherBasicTestTestCaseProps = anotherBasicTestTestCase.children("properties").children("property"); + assertThat(anotherBasicTestTestCaseProps.matchAttr("name", "test_id").attr("value")) + .isEqualTo("ID:anotherBasicTest"); + assertThat(anotherBasicTestTestCaseProps.matchAttr("name", "test_key").attr("value")) + .isEqualTo("KEY:anotherBasicTest"); + assertThat(anotherBasicTestTestCaseProps.matchAttr("name", "test_summary").attr("value")) + .isEqualTo("SUMMARY:anotherBasicTest"); + assertThat(anotherBasicTestTestCaseProps.matchAttr("name", "test_description").text()) + .isEqualTo("DESCRIPTION:anotherBasicTest"); + } @Test public void shouldSupportCustomReportNames() throws Exception { diff --git a/src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestClass.java b/src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestClass.java new file mode 100644 index 0000000..4ba16cc --- /dev/null +++ b/src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestClass.java @@ -0,0 +1,58 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * https://www.eclipse.org/legal/epl-v20.html + */ + +package app.getxray.xray.junit.customjunitxml.data; + +import app.getxray.xray.junit.customjunitxml.annotations.Requirement; +import app.getxray.xray.junit.customjunitxml.annotations.XrayTest; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestFactory; + +@Disabled +public class MockedTestClass { + + @XrayTest( + key = "ABC-123", + id = "868", + summary = "some summary", + description = "some description" + ) + @Requirement({"REQ-1", "REQ-2"}) + public void annotatedWithValues() { + + } + + @XrayTest + @Requirement({}) + public void annotatedWithEmptyValues() { + + } + + public void notAnnotatedTest() { + + } + + @DisplayName("display name") + public void annotatedWithDisplayName() { + + } + + @XrayTest(summary = "xray summary") + @DisplayName("display name") + public void annotatedWithXrayTestAndDisplayName() { + + } + + @TestFactory + public void withTestFactory() { + + } +} diff --git a/src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestWithDisplayNameGeneratorClass.java b/src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestWithDisplayNameGeneratorClass.java new file mode 100644 index 0000000..74830fe --- /dev/null +++ b/src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestWithDisplayNameGeneratorClass.java @@ -0,0 +1,46 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v2.0 which + * accompanies this distribution and is available at + * + * https://www.eclipse.org/legal/epl-v20.html + */ + +package app.getxray.xray.junit.customjunitxml.data; + +import app.getxray.xray.junit.customjunitxml.annotations.XrayTest; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; + +import java.lang.reflect.Method; + +@Disabled +@DisplayNameGeneration(MockedTestWithDisplayNameGeneratorClass.CustomGenerator.class) +public class MockedTestWithDisplayNameGeneratorClass { + + public static class CustomGenerator implements DisplayNameGenerator { + @Override + public String generateDisplayNameForClass(Class testClass) { + return "DisplayNameForClass"; + } + + @Override + public String generateDisplayNameForNestedClass(Class nestedClass) { + return "DisplayNameForNestedClass"; + } + + @Override + public String generateDisplayNameForMethod(Class testClass, Method testMethod) { + return "DisplayNameForMethod"; + } + } + + @XrayTest() + public void withDisplayNameGenerator() { + + } + +} From 950fc21b483c136c5d3057d81c685e70aba01bed Mon Sep 17 00:00:00 2001 From: Maciej Kucharczyk Date: Wed, 14 Aug 2024 16:03:05 +0200 Subject: [PATCH 2/3] SonarCloud issues fixed --- .../junit/customjunitxml/XmlReportWriter.java | 24 +++---- .../DefaultXrayTestInfoReaderTest.java | 68 +++++++++---------- .../customjunitxml/data/MockedTestClass.java | 12 ++-- ...ckedTestWithDisplayNameGeneratorClass.java | 2 +- 4 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/main/java/app/getxray/xray/junit/customjunitxml/XmlReportWriter.java b/src/main/java/app/getxray/xray/junit/customjunitxml/XmlReportWriter.java index f949080..43a30e4 100644 --- a/src/main/java/app/getxray/xray/junit/customjunitxml/XmlReportWriter.java +++ b/src/main/java/app/getxray/xray/junit/customjunitxml/XmlReportWriter.java @@ -278,23 +278,23 @@ private void writeTestcase(TestIdentifier testIdentifier, AggregatedTestResult t addProperty(writer, "requirements", String.join(",", requirements)); } - Optional test_key = xrayTestMetadataReader.getKey(testIdentifier); - if (test_key.isPresent()) { - addProperty(writer, "test_key", test_key.get()); + Optional testKeyOpt = xrayTestMetadataReader.getKey(testIdentifier); + if (testKeyOpt.isPresent()) { + addProperty(writer, "test_key", testKeyOpt.get()); } - Optional test_id = xrayTestMetadataReader.getId(testIdentifier); - if (test_id.isPresent()) { - addProperty(writer, "test_id", test_id.get()); + Optional testIdOpt = xrayTestMetadataReader.getId(testIdentifier); + if (testIdOpt.isPresent()) { + addProperty(writer, "test_id", testIdOpt.get()); } - Optional test_description = xrayTestMetadataReader.getDescription(testIdentifier); - if (test_description.isPresent()) { - addPropertyWithInnerContent(writer, "test_description", test_description.get()); + Optional testDescriptionOpt = xrayTestMetadataReader.getDescription(testIdentifier); + if (testDescriptionOpt.isPresent()) { + addPropertyWithInnerContent(writer, "test_description", testDescriptionOpt.get()); } - Optional test_summary = xrayTestMetadataReader.getSummary(testIdentifier); - if (test_summary.isPresent()) { - addProperty(writer, "test_summary", test_summary.get()); + Optional testSummaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); + if (testSummaryOpt.isPresent()) { + addProperty(writer, "test_summary", testSummaryOpt.get()); } List tags = testIdentifier.getTags().stream().map(TestTag::getName).map(String::trim) diff --git a/src/test/java/app/getxray/xray/junit/customjunitxml/DefaultXrayTestInfoReaderTest.java b/src/test/java/app/getxray/xray/junit/customjunitxml/DefaultXrayTestInfoReaderTest.java index 8a19af7..456db30 100644 --- a/src/test/java/app/getxray/xray/junit/customjunitxml/DefaultXrayTestInfoReaderTest.java +++ b/src/test/java/app/getxray/xray/junit/customjunitxml/DefaultXrayTestInfoReaderTest.java @@ -32,13 +32,13 @@ class DefaultXrayTestInfoReaderTest { private final XrayTestMetadataReader xrayTestMetadataReader = new DefaultXrayTestMetadataReader(); - private static TestDescriptor XRAYTEST_ANNOTATED; - private static TestDescriptor XRAYTEST_EMPTY_ANNOTATION; - private static TestDescriptor NOT_ANNOTATED; - private static TestDescriptor DISPLAY_NAME_ANNOTATED; - private static TestDescriptor XRAYTEST_AND_DISPLAY_NAME_ANNOTATED; - private static TestDescriptor WITH_DISPLAY_NAME_GENERATOR; - private static TestDescriptor WITH_TEST_FACTORY; + private static TestDescriptor testWithXraytestAnnotation; + private static TestDescriptor testWithXraytestEmptyAnnotation; + private static TestDescriptor testNotAnnotated; + private static TestDescriptor testWithDisplayNameAnnotation; + private static TestDescriptor testWithXraytestAndDisplayNameAnnotation; + private static TestDescriptor testWithDisplayNameGenerator; + private static TestDescriptor testWithTestFactoryAnnotation; @BeforeAll static void setUp() throws NoSuchMethodException { @@ -66,43 +66,43 @@ public Set keySet() { } ); - XRAYTEST_ANNOTATED = new TestMethodTestDescriptor( + testWithXraytestAnnotation = new TestMethodTestDescriptor( UniqueId.forEngine("foo"), MockedTestClass.class, MockedTestClass.class.getMethod("annotatedWithValues"), jupiterConfiguration ); - XRAYTEST_EMPTY_ANNOTATION = new TestMethodTestDescriptor( + testWithXraytestEmptyAnnotation = new TestMethodTestDescriptor( UniqueId.forEngine("foo"), MockedTestClass.class, MockedTestClass.class.getMethod("annotatedWithEmptyValues"), jupiterConfiguration ); - NOT_ANNOTATED = new TestMethodTestDescriptor( + testNotAnnotated = new TestMethodTestDescriptor( UniqueId.forEngine("foo"), MockedTestClass.class, MockedTestClass.class.getMethod("notAnnotatedTest"), jupiterConfiguration ); - DISPLAY_NAME_ANNOTATED = new TestMethodTestDescriptor( + testWithDisplayNameAnnotation = new TestMethodTestDescriptor( UniqueId.forEngine("foo"), MockedTestClass.class, MockedTestClass.class.getMethod("annotatedWithDisplayName"), jupiterConfiguration ); - XRAYTEST_AND_DISPLAY_NAME_ANNOTATED = new TestMethodTestDescriptor( + testWithXraytestAndDisplayNameAnnotation = new TestMethodTestDescriptor( UniqueId.forEngine("foo"), MockedTestClass.class, MockedTestClass.class.getMethod("annotatedWithXrayTestAndDisplayName"), jupiterConfiguration ); - WITH_DISPLAY_NAME_GENERATOR = new TestMethodTestDescriptor( + testWithDisplayNameGenerator = new TestMethodTestDescriptor( UniqueId.forEngine("foo"), MockedTestWithDisplayNameGeneratorClass.class, MockedTestWithDisplayNameGeneratorClass.class.getMethod("withDisplayNameGenerator"), jupiterConfiguration ); - WITH_TEST_FACTORY = new TestMethodTestDescriptor( + testWithTestFactoryAnnotation = new TestMethodTestDescriptor( UniqueId.forEngine("foo"), MockedTestClass.class, MockedTestClass.class.getMethod("withTestFactory"), @@ -113,7 +113,7 @@ public Set keySet() { @Test void shouldReturnKeyFromXrayTestAnnotation() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_ANNOTATED); + TestIdentifier testIdentifier = TestIdentifier.from(testWithXraytestAnnotation); // WHEN Optional keyOpt = xrayTestMetadataReader.getKey(testIdentifier); // THEN @@ -124,7 +124,7 @@ void shouldReturnKeyFromXrayTestAnnotation() { @Test void shouldReturnOptionalEmptyFromXrayTestAnnotationWithEmptyKey() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_EMPTY_ANNOTATION); + TestIdentifier testIdentifier = TestIdentifier.from(testWithXraytestEmptyAnnotation); // WHEN Optional keyOpt = xrayTestMetadataReader.getKey(testIdentifier); // THEN @@ -135,7 +135,7 @@ void shouldReturnOptionalEmptyFromXrayTestAnnotationWithEmptyKey() { @Test void shouldReturnOptionalEmptyKeyWhenMethodNotAnnotated() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(NOT_ANNOTATED); + TestIdentifier testIdentifier = TestIdentifier.from(testNotAnnotated); // WHEN Optional keyOpt = xrayTestMetadataReader.getKey(testIdentifier); // THEN @@ -146,7 +146,7 @@ void shouldReturnOptionalEmptyKeyWhenMethodNotAnnotated() { @Test void shouldReturnIdFromXrayTestAnnotation() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_ANNOTATED); + TestIdentifier testIdentifier = TestIdentifier.from(testWithXraytestAnnotation); // WHEN Optional idOpt = xrayTestMetadataReader.getId(testIdentifier); // THEN @@ -157,7 +157,7 @@ void shouldReturnIdFromXrayTestAnnotation() { @Test void shouldReturnOptionalEmptyFromXrayTestAnnotationWithEmptyId() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_EMPTY_ANNOTATION); + TestIdentifier testIdentifier = TestIdentifier.from(testWithXraytestEmptyAnnotation); // WHEN Optional idOpt = xrayTestMetadataReader.getId(testIdentifier); // THEN @@ -168,7 +168,7 @@ void shouldReturnOptionalEmptyFromXrayTestAnnotationWithEmptyId() { @Test void shouldReturnOptionalEmptyIdWhenMethodNotAnnotated() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(NOT_ANNOTATED); + TestIdentifier testIdentifier = TestIdentifier.from(testNotAnnotated); // WHEN Optional idOpt = xrayTestMetadataReader.getId(testIdentifier); // THEN @@ -179,7 +179,7 @@ void shouldReturnOptionalEmptyIdWhenMethodNotAnnotated() { @Test void shouldReturnSummaryFromXrayTestAnnotation() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_ANNOTATED); + TestIdentifier testIdentifier = TestIdentifier.from(testWithXraytestAnnotation); // WHEN Optional summaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); // THEN @@ -190,7 +190,7 @@ void shouldReturnSummaryFromXrayTestAnnotation() { @Test void shouldReturnOptionalEmptyFromXrayTestAnnotationWithEmptySummary() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_EMPTY_ANNOTATION); + TestIdentifier testIdentifier = TestIdentifier.from(testWithXraytestEmptyAnnotation); // WHEN Optional summaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); // THEN @@ -201,7 +201,7 @@ void shouldReturnOptionalEmptyFromXrayTestAnnotationWithEmptySummary() { @Test void shouldReturnOptionalEmptySummaryWhenMethodNotAnnotated() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(NOT_ANNOTATED); + TestIdentifier testIdentifier = TestIdentifier.from(testNotAnnotated); // WHEN Optional summaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); // THEN @@ -212,7 +212,7 @@ void shouldReturnOptionalEmptySummaryWhenMethodNotAnnotated() { @Test void shouldReturnDisplayNameWhenNotAnnotatedWithXrayTest() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(DISPLAY_NAME_ANNOTATED); + TestIdentifier testIdentifier = TestIdentifier.from(testWithDisplayNameAnnotation); // WHEN Optional summaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); // THEN @@ -223,7 +223,7 @@ void shouldReturnDisplayNameWhenNotAnnotatedWithXrayTest() { @Test void shouldReturnDisplayNameFromXrayTestAnnotationWhenAlsoAnnotatedWithDisplayName() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_AND_DISPLAY_NAME_ANNOTATED); + TestIdentifier testIdentifier = TestIdentifier.from(testWithXraytestAndDisplayNameAnnotation); // WHEN Optional summaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); // THEN @@ -234,7 +234,7 @@ void shouldReturnDisplayNameFromXrayTestAnnotationWhenAlsoAnnotatedWithDisplayNa @Test void shouldReturnDefaultDisplayNameWhenAnnotatedWithDisplayNameGenerator() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(WITH_DISPLAY_NAME_GENERATOR); + TestIdentifier testIdentifier = TestIdentifier.from(testWithDisplayNameGenerator); // WHEN Optional summaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); // THEN @@ -245,7 +245,7 @@ void shouldReturnDefaultDisplayNameWhenAnnotatedWithDisplayNameGenerator() { @Test void shouldReturnDefaultDisplayNameWhenAnnotatedWithTestFactory() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(WITH_TEST_FACTORY); + TestIdentifier testIdentifier = TestIdentifier.from(testWithTestFactoryAnnotation); // WHEN Optional summaryOpt = xrayTestMetadataReader.getSummary(testIdentifier); // THEN @@ -256,7 +256,7 @@ void shouldReturnDefaultDisplayNameWhenAnnotatedWithTestFactory() { @Test void shouldReturnDescriptionFromXrayTestAnnotation() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_ANNOTATED); + TestIdentifier testIdentifier = TestIdentifier.from(testWithXraytestAnnotation); // WHEN Optional descriptionOpt = xrayTestMetadataReader.getDescription(testIdentifier); // THEN @@ -267,7 +267,7 @@ void shouldReturnDescriptionFromXrayTestAnnotation() { @Test void shouldReturnOptionalEmptyFromXrayTestAnnotationWithEmptyDescription() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_EMPTY_ANNOTATION); + TestIdentifier testIdentifier = TestIdentifier.from(testWithXraytestEmptyAnnotation); // WHEN Optional descriptionOpt = xrayTestMetadataReader.getDescription(testIdentifier); // THEN @@ -278,7 +278,7 @@ void shouldReturnOptionalEmptyFromXrayTestAnnotationWithEmptyDescription() { @Test void shouldReturnOptionalEmptyDescriptionWhenMethodNotAnnotated() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(NOT_ANNOTATED); + TestIdentifier testIdentifier = TestIdentifier.from(testNotAnnotated); // WHEN Optional descriptionOpt = xrayTestMetadataReader.getDescription(testIdentifier); // THEN @@ -289,7 +289,7 @@ void shouldReturnOptionalEmptyDescriptionWhenMethodNotAnnotated() { @Test void shouldReturnRequirementsFromRequirementsAnnotation() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_ANNOTATED); + TestIdentifier testIdentifier = TestIdentifier.from(testWithXraytestAnnotation); // WHEN List requirements = xrayTestMetadataReader.getRequirements(testIdentifier); // THEN @@ -300,7 +300,7 @@ void shouldReturnRequirementsFromRequirementsAnnotation() { @Test void shouldReturnEmptyListFromRequirementsAnnotationWithEmptyArray() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(XRAYTEST_EMPTY_ANNOTATION); + TestIdentifier testIdentifier = TestIdentifier.from(testWithXraytestEmptyAnnotation); // WHEN List requirements = xrayTestMetadataReader.getRequirements(testIdentifier); // THEN @@ -311,11 +311,11 @@ void shouldReturnEmptyListFromRequirementsAnnotationWithEmptyArray() { @Test void shouldReturnEmptyListOfRequirementsWhenMethodNotAnnotated() { // GIVEN - TestIdentifier testIdentifier = TestIdentifier.from(NOT_ANNOTATED); + TestIdentifier testIdentifier = TestIdentifier.from(testNotAnnotated); // WHEN List requirements = xrayTestMetadataReader.getRequirements(testIdentifier); // THEN assertThat(requirements) .isEmpty(); } -} \ No newline at end of file +} diff --git a/src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestClass.java b/src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestClass.java index 4ba16cc..680890f 100644 --- a/src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestClass.java +++ b/src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestClass.java @@ -27,32 +27,32 @@ public class MockedTestClass { ) @Requirement({"REQ-1", "REQ-2"}) public void annotatedWithValues() { - + // it's a dummy test definition, no implementation needed } @XrayTest @Requirement({}) public void annotatedWithEmptyValues() { - + // it's a dummy test definition, no implementation needed } public void notAnnotatedTest() { - + // it's a dummy test definition, no implementation needed } @DisplayName("display name") public void annotatedWithDisplayName() { - + // it's a dummy test definition, no implementation needed } @XrayTest(summary = "xray summary") @DisplayName("display name") public void annotatedWithXrayTestAndDisplayName() { - + // it's a dummy test definition, no implementation needed } @TestFactory public void withTestFactory() { - + // it's a dummy test definition, no implementation needed } } diff --git a/src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestWithDisplayNameGeneratorClass.java b/src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestWithDisplayNameGeneratorClass.java index 74830fe..7267d47 100644 --- a/src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestWithDisplayNameGeneratorClass.java +++ b/src/test/java/app/getxray/xray/junit/customjunitxml/data/MockedTestWithDisplayNameGeneratorClass.java @@ -40,7 +40,7 @@ public String generateDisplayNameForMethod(Class testClass, Method testMethod @XrayTest() public void withDisplayNameGenerator() { - + // it's a dummy test definition, no implementation needed } } From eeb1f609055397e841f804f98deb7472ba2d52cb Mon Sep 17 00:00:00 2001 From: Maciej Kucharczyk Date: Wed, 14 Aug 2024 17:15:14 +0200 Subject: [PATCH 3/3] Update docs --- README.md | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ace498..e16b3da 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,8 @@ If you want, you may configure certain aspects of this extension. The defaults s - `report_directory`: the directory where to generate the report, in relative or absolute format. Default is "target" - `add_timestamp_to_report_filename`: add a timestamp based suffix to the report. Default is "false". - `report_only_annotated_tests`: only include tests annotated with @XrayTest or @Requirement. Default is "false". -- `reports_per_class`: generate JUnit XML reports per test class instead of a single report with all results; if true, `report_filename`, and `add_timestamp_to_report_filename` are ignored. Default is "false". +- `reports_per_class`: generate JUnit XML reports per test class instead of a single report with all results; if true, `report_filename`, and `add_timestamp_to_report_filename` are ignored. Default is "false". +- `test_metadata_reader`: override the default logic responsible for reading meta-information about test methods. Example: @@ -72,6 +73,7 @@ report_directory=reports add_timestamp_to_report_filename=true report_only_annotated_tests=false reports_per_class=false +test_metadata_reader=com.example.CustomTestMetadataReader ``` ## How to use @@ -190,6 +192,74 @@ public class XrayEnabledTestExamples { } ``` +### Customizing how test metadata is read + +When generating the report, it's allowed to customize the way the test method information is read. +By default, test information such as id, key, summary, description and requirements are read directly from @XrayTest and @Requirements annotations. +This behavior can be overridden by the user when he wants to change the way these meta-information are generated, or when he wants to use their own annotations to describe the tests. + +To do this, you need to create a public class with a no-argument constructor that implements the `app.getxray.xray.junit.customjunitxml.XrayTestMetadataReader` interface (or extend `app.getxray.xray.junit.customjunitxml.DefaultXrayTestMetadataReader` class). +Then must add `test_metadata_reader` entry with the class name to the `xray-junit-extensions.properties` file. + + +#### Example: Custom test metadata reader to read Jira key from custom @JiraKey annotation + +_JiraKey.java_ +```java +package com.example; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface JiraKey { + String value(); +} +``` + +_CustomTestMetadataReader.java_ +```java +package com.example; + +import app.getxray.xray.junit.customjunitxml.DefaultXrayTestMetadataReader; +import org.junit.platform.launcher.TestIdentifier; + +import java.util.Optional; + +public class CustomTestMetadataReader extends DefaultXrayTestMetadataReader { + + @Override + public Optional getKey(TestIdentifier testIdentifier) { + return getTestMethodAnnotation(testIdentifier, JiraKey.class) + .map(JiraKey::value) + .filter(s -> !s.isEmpty()); + } +} +``` + +_xray-junit-extensions.properties_ +``` +test_metadata_reader=com.example.CustomTestMetadataReader +``` + +_SimpleTest.java_ +```java +package com.example; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class SimpleTest { + + @Test + @JiraKey("CALC-123") + @DisplayName("simple test") + void simpleTest() { + // ... + } +} +``` + ## Other features and limitations ### Name of Tests @@ -200,6 +270,9 @@ The summary of the Test issue will be set based on these rules (the first that a * based on the `@DisplayName` annotation, or the display name of dynamically created tests from a TestFactory; * based on the test's method name. +> [!TIP] +> This behavior can be changed by defining a custom test metadata reader. + ### Parameterized and repeated tests For the time being, and similar to what happened with legacy JUnit XML reports produces with JUnit 4, parameterized tests (i.e. annotated with `@ParameterizedTest`) will be mapped to similar `` elements in the JUnit XML report.