diff --git a/allure-java-commons/src/main/java/io/qameta/allure/util/ResultsUtils.java b/allure-java-commons/src/main/java/io/qameta/allure/util/ResultsUtils.java index 39393f016..aa86319d2 100644 --- a/allure-java-commons/src/main/java/io/qameta/allure/util/ResultsUtils.java +++ b/allure-java-commons/src/main/java/io/qameta/allure/util/ResultsUtils.java @@ -384,14 +384,13 @@ private static String getStackTraceAsString(final Throwable throwable) { return stringWriter.toString(); } - @SuppressWarnings("deprecation") public static void processDescription(final ClassLoader classLoader, final Method method, final Consumer setDescription, final Consumer setDescriptionHtml) { if (method.isAnnotationPresent(Description.class)) { final Description annotation = method.getAnnotation(Description.class); - if (annotation.useJavaDoc() || "".equals(annotation.value())) { + if ("".equals(annotation.value())) { getJavadocDescription(classLoader, method) .ifPresent(setDescriptionHtml); } else { diff --git a/allure-junit4/build.gradle.kts b/allure-junit4/build.gradle.kts index 9597c6391..d8117ef55 100644 --- a/allure-junit4/build.gradle.kts +++ b/allure-junit4/build.gradle.kts @@ -6,6 +6,7 @@ dependencies { api(project(":allure-java-commons")) implementation("junit:junit:$junitVersion") implementation(project(":allure-test-filter")) + testAnnotationProcessor(project(":allure-descriptions-javadoc")) testImplementation("org.assertj:assertj-core") testImplementation("org.junit.jupiter:junit-jupiter-api") testImplementation("org.mockito:mockito-core") diff --git a/allure-junit4/src/main/java/io/qameta/allure/junit4/AllureJunit4.java b/allure-junit4/src/main/java/io/qameta/allure/junit4/AllureJunit4.java index 72589a82b..7880d6359 100644 --- a/allure-junit4/src/main/java/io/qameta/allure/junit4/AllureJunit4.java +++ b/allure-junit4/src/main/java/io/qameta/allure/junit4/AllureJunit4.java @@ -29,12 +29,15 @@ import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static io.qameta.allure.util.AnnotationUtils.getLabels; import static io.qameta.allure.util.AnnotationUtils.getLinks; @@ -46,6 +49,7 @@ import static io.qameta.allure.util.ResultsUtils.createTestClassLabel; import static io.qameta.allure.util.ResultsUtils.createTestMethodLabel; import static io.qameta.allure.util.ResultsUtils.createThreadLabel; +import static io.qameta.allure.util.ResultsUtils.getJavadocDescription; import static io.qameta.allure.util.ResultsUtils.getProvidedLabels; import static io.qameta.allure.util.ResultsUtils.getStatus; import static io.qameta.allure.util.ResultsUtils.getStatusDetails; @@ -177,8 +181,38 @@ private Optional getDisplayName(final Description result) { } private Optional getDescription(final Description result) { - return Optional.ofNullable(result.getAnnotation(io.qameta.allure.Description.class)) - .map(io.qameta.allure.Description::value); + final io.qameta.allure.Description annotation = result + .getAnnotation(io.qameta.allure.Description.class); + + if (Objects.isNull(annotation)) { + return Optional.empty(); + } + + if (!"".equals(annotation.value())) { + return Optional.of(annotation.value()); + } + + // since we have no access to method & method parameter types + // we simply find all the methods within test class that matching + // specified method name. If there is only one result, consider it a + // test. + final Class testClass = result.getTestClass(); + final String methodName = result.getMethodName(); + if (Objects.nonNull(testClass) && Objects.nonNull(methodName)) { + final List found = Stream.of(testClass.getMethods()) + .filter(method -> Objects.equals(methodName, method.getName())) + .collect(Collectors.toList()); + if (found.size() != 1) { + return Optional.empty(); + } + + final Method method = found.get(0); + return getJavadocDescription( + method.getDeclaringClass().getClassLoader(), + method + ); + } + return Optional.empty(); } private List extractLinks(final Description description) { @@ -247,6 +281,7 @@ private TestResult createTestResult(final String uuid, final Description descrip testResult.getLinks().addAll(extractLinks(description)); getDisplayName(description).ifPresent(testResult::setName); + getDescription(description).ifPresent(testResult::setDescription); return testResult; } diff --git a/allure-junit4/src/test/java/io/qameta/allure/junit4/AllureJunit4Test.java b/allure-junit4/src/test/java/io/qameta/allure/junit4/AllureJunit4Test.java index 2d1d29a51..7da9aba36 100644 --- a/allure-junit4/src/test/java/io/qameta/allure/junit4/AllureJunit4Test.java +++ b/allure-junit4/src/test/java/io/qameta/allure/junit4/AllureJunit4Test.java @@ -23,6 +23,7 @@ import io.qameta.allure.junit4.samples.AssumptionFailedTest; import io.qameta.allure.junit4.samples.BrokenTest; import io.qameta.allure.junit4.samples.BrokenWithoutMessageTest; +import io.qameta.allure.junit4.samples.DescriptionsJavadoc; import io.qameta.allure.junit4.samples.FailedTest; import io.qameta.allure.junit4.samples.FilterSimpleTests; import io.qameta.allure.junit4.samples.IgnoredClassTest; @@ -33,6 +34,7 @@ import io.qameta.allure.junit4.samples.TestWithAnnotations; import io.qameta.allure.junit4.samples.TestWithSteps; import io.qameta.allure.junit4.samples.TestWithTimeout; +import io.qameta.allure.junit4.samples.TheoriesTest; import io.qameta.allure.model.Label; import io.qameta.allure.model.Link; import io.qameta.allure.model.Stage; @@ -387,6 +389,32 @@ void shouldFilterByAllureId() { .containsExactly("io.qameta.allure.junit4.samples.FilterSimpleTests.test3"); } + @Test + void shouldProcessJavadocDescriptions() { + final AllureResults results = runClasses(DescriptionsJavadoc.class); + + final List testResults = results.getTestResults(); + + assertThat(testResults) + .extracting(TestResult::getName, TestResult::getDescription) + .containsExactlyInAnyOrder( + tuple("simpleTest", "Description from javadoc.") + ); + } + + @Test + void shouldProcessJavadocDescriptionsInTheories() { + final AllureResults results = runClasses(TheoriesTest.class); + + final List testResults = results.getTestResults(); + + assertThat(testResults) + .extracting(TestResult::getName, TestResult::getDescription) + .containsExactlyInAnyOrder( + tuple("simpleTest", "Description from javadoc.") + ); + } + @Step("Run classes {classes}") private AllureResults runClasses(final Class... classes) { return runClasses(null, classes); diff --git a/allure-junit4/src/test/java/io/qameta/allure/junit4/samples/DescriptionsJavadoc.java b/allure-junit4/src/test/java/io/qameta/allure/junit4/samples/DescriptionsJavadoc.java new file mode 100644 index 000000000..467f4c513 --- /dev/null +++ b/allure-junit4/src/test/java/io/qameta/allure/junit4/samples/DescriptionsJavadoc.java @@ -0,0 +1,33 @@ +/* + * Copyright 2023 Qameta Software OÜ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.qameta.allure.junit4.samples; + +import io.qameta.allure.Description; +import org.junit.Test; + +/** + * @author charlie (Dmitry Baev). + */ +public class DescriptionsJavadoc { + + /** + * Description from javadoc. + */ + @Description + @Test + public void simpleTest() { + } +} diff --git a/allure-junit4/src/test/java/io/qameta/allure/junit4/samples/TheoriesTest.java b/allure-junit4/src/test/java/io/qameta/allure/junit4/samples/TheoriesTest.java new file mode 100644 index 000000000..22768d2b6 --- /dev/null +++ b/allure-junit4/src/test/java/io/qameta/allure/junit4/samples/TheoriesTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2023 Qameta Software OÜ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.qameta.allure.junit4.samples; + +import io.qameta.allure.Description; +import org.junit.experimental.theories.DataPoints; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +/** + * @author charlie (Dmitry Baev). + */ +@RunWith(Theories.class) +public class TheoriesTest { + + @DataPoints + public static final String[] VALUES = new String[]{ + "first", + "second" + }; + + /** + * Description from javadoc. + */ + @Description + @Theory + public void simpleTest(final String value) { + System.out.println(value); + } +}