From 922407fd293132045a5cfa4a760ff5f2774f1e49 Mon Sep 17 00:00:00 2001 From: Dmitry Baev Date: Fri, 3 Sep 2021 16:27:51 +0300 Subject: [PATCH 1/3] add new param annotation --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .../main/java/io/qameta/allure/Allure.java | 50 ++++++++++++- .../src/main/java/io/qameta/allure/Param.java | 71 +++++++++++++++++++ .../io/qameta/allure/util/AspectUtils.java | 34 +++++---- .../io/qameta/allure/util/ParameterUtils.java | 64 +++++++++++++++++ .../io/qameta/allure/util/ResultsUtils.java | 16 +++-- .../java/io/qameta/allure/AllureTest.java | 25 +++++++ .../allure/aspects/StepsAspectsTest.java | 31 ++++++++ ...ectUtilsTest.java => ObjectUtilsTest.java} | 2 +- 9 files changed, 274 insertions(+), 21 deletions(-) create mode 100644 allure-java-commons/src/main/java/io/qameta/allure/Param.java create mode 100644 allure-java-commons/src/main/java/io/qameta/allure/util/ParameterUtils.java rename allure-java-commons/src/test/java/io/qameta/allure/util/{AspectUtilsTest.java => ObjectUtilsTest.java} (98%) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 0dec83312..8178c9b61 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,7 +3,7 @@ Thank you so much for sending us a pull request! Make sure you have a clear name for your pull request. The name should start with a capital letter and no dot is required in the end of the sentence. -To link the request with isses use the following notation: (fixes #123, fixes #321\) +To link the request with issues use the following notation: (fixes #123, fixes #321\) An example of good pull request names: * Add Cucumber integration (fixes #123\) diff --git a/allure-java-commons/src/main/java/io/qameta/allure/Allure.java b/allure-java-commons/src/main/java/io/qameta/allure/Allure.java index 9e494de21..bfe433f8e 100644 --- a/allure-java-commons/src/main/java/io/qameta/allure/Allure.java +++ b/allure-java-commons/src/main/java/io/qameta/allure/Allure.java @@ -247,12 +247,60 @@ public static void label(final String name, final String value) { /** * Adds parameter to current test or step (or fixture) if any. Takes no effect * if no test run at the moment. + *

+ * Shortcut for {@link #parameter(String, Object, Boolean, Parameter.Mode)}. * * @param name the name of parameter. * @param value the value of parameter. */ public static T parameter(final String name, final T value) { - final Parameter parameter = createParameter(name, value); + return parameter(name, value, null, null); + } + + /** + * Adds parameter to current test or step (or fixture) if any. Takes no effect + * if no test run at the moment. + *

+ * Shortcut for {@link #parameter(String, Object, Boolean, Parameter.Mode)}. + * + * @param name the name of parameter. + * @param value the value of parameter. + * @param excluded true if parameter should be excluded from history key calculation, false otherwise. + * @return the specified value. + */ + public static T parameter(final String name, final T value, final Boolean excluded) { + return parameter(name, value, excluded, null); + } + + /** + * Adds parameter to current test or step (or fixture) if any. Takes no effect + * if no test run at the moment. + *

+ * Shortcut for {@link #parameter(String, Object, Boolean, Parameter.Mode)}. + * + * @param name the name of parameter. + * @param value the value of parameter. + * @param mode the parameter mode. + * @return the specified value. + */ + public static T parameter(final String name, final T value, + final Parameter.Mode mode) { + return parameter(name, value, null, mode); + } + + /** + * Adds parameter to current test or step (or fixture) if any. Takes no effect + * if no test run at the moment. + * + * @param name the name of parameter. + * @param value the value of parameter. + * @param excluded true if parameter should be excluded from history key calculation, false otherwise. + * @param mode the parameter mode. + * @return the specified value. + */ + public static T parameter(final String name, final T value, + final Boolean excluded, final Parameter.Mode mode) { + final Parameter parameter = createParameter(name, value, excluded, mode); getLifecycle().updateTestCase(testResult -> testResult.getParameters().add(parameter)); return value; } diff --git a/allure-java-commons/src/main/java/io/qameta/allure/Param.java b/allure-java-commons/src/main/java/io/qameta/allure/Param.java new file mode 100644 index 000000000..33e34f5bc --- /dev/null +++ b/allure-java-commons/src/main/java/io/qameta/allure/Param.java @@ -0,0 +1,71 @@ +/* + * Copyright 2019 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; + +import io.qameta.allure.model.Parameter; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation used to add parameters to results + * from method parameters. + * + * @see Parameter + * @see Parameter.Mode + * @see Allure#parameter(String, Object) + */ +@Documented +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +public @interface Param { + + /** + * Alias for {@link #name()}. Overrides value, specified in {@link #name()}. + */ + String value() default ""; + + /** + * The name of parameter. Be careful, changing parameter's name + * may affect method signature and, as result, may get different + * test case generated. + *

+ * If not specified, the parameter name from reflection will be used. + * + * @return the name of parameter. + */ + String name() default ""; + + /** + * The parameter mode. + * + * @return the parameter mode. + */ + Parameter.Mode mode() default Parameter.Mode.DEFAULT; + + /** + * Set it to true to exclude the parameter from historyKey generation. + * + * @return true if parameter is excluded, false otherwise. + */ + boolean excluded() default false; + +} diff --git a/allure-java-commons/src/main/java/io/qameta/allure/util/AspectUtils.java b/allure-java-commons/src/main/java/io/qameta/allure/util/AspectUtils.java index 98c83e7b6..640298f9d 100644 --- a/allure-java-commons/src/main/java/io/qameta/allure/util/AspectUtils.java +++ b/allure-java-commons/src/main/java/io/qameta/allure/util/AspectUtils.java @@ -15,6 +15,7 @@ */ package io.qameta.allure.util; +import io.qameta.allure.Param; import io.qameta.allure.model.Parameter; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.reflect.MethodSignature; @@ -25,6 +26,7 @@ import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.IntStream; +import java.util.stream.Stream; import static io.qameta.allure.util.NamingUtils.processNameTemplate; import static io.qameta.allure.util.ResultsUtils.createParameter; @@ -38,19 +40,6 @@ private AspectUtils() { throw new IllegalStateException("Do not instance"); } - /** - * @deprecated use {@link AspectUtils#getName(String,JoinPoint)} instead. - */ - @Deprecated - public static String getName(final String nameTemplate, - final MethodSignature methodSignature, - final Object... args) { - return Optional.of(nameTemplate) - .filter(v -> !v.isEmpty()) - .map(value -> processNameTemplate(value, getParametersMap(methodSignature, args))) - .orElseGet(methodSignature::getName); - } - public static String getName(final String nameTemplate, final JoinPoint joinPoint) { return Optional.of(nameTemplate) .filter(v -> !v.isEmpty()) @@ -81,9 +70,26 @@ public static Map getParametersMap(final JoinPoint joinPoint) { } public static List getParameters(final MethodSignature signature, final Object... args) { + final java.lang.reflect.Parameter[] params = signature.getMethod().getParameters(); return IntStream .range(0, args.length) - .mapToObj(index -> createParameter(signature.getParameterNames()[index], args[index])) + .mapToObj(index -> { + final Parameter parameter = createParameter(signature.getParameterNames()[index], args[index]); + final java.lang.reflect.Parameter ref = params[index]; + Stream.of(ref.getAnnotationsByType(Param.class)) + .findFirst() + .ifPresent(param -> { + Stream.of(param.value(), param.name()) + .map(String::trim) + .filter(name -> name.length() > 0) + .findFirst() + .ifPresent(parameter::setName); + + parameter.setMode(param.mode()); + parameter.setExcluded(param.excluded()); + }); + return parameter; + }) .collect(Collectors.toList()); } diff --git a/allure-java-commons/src/main/java/io/qameta/allure/util/ParameterUtils.java b/allure-java-commons/src/main/java/io/qameta/allure/util/ParameterUtils.java new file mode 100644 index 000000000..f0e68f7ec --- /dev/null +++ b/allure-java-commons/src/main/java/io/qameta/allure/util/ParameterUtils.java @@ -0,0 +1,64 @@ +/* + * Copyright 2021 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.util; + +import io.qameta.allure.Param; +import io.qameta.allure.model.Parameter; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +/** + * @author charlie (Dmitry Baev). + */ +public final class ParameterUtils { + + private ParameterUtils() { + throw new IllegalStateException("do not instance"); + } + + public static List createParameters(final Method method, + final Object... args) { + final java.lang.reflect.Parameter[] parameters = method.getParameters(); + return IntStream.range(0, parameters.length) + .mapToObj(i -> { + final java.lang.reflect.Parameter parameter = parameters[i]; + final Object value = args[i]; + final Param annotation = parameter.getAnnotation(Param.class); + if (Objects.isNull(annotation)) { + return ResultsUtils.createParameter(parameter.getName(), value); + } + final String name = Stream.of(annotation.value(), annotation.name(), parameter.getName()) + .map(String::trim) + .filter(s -> s.length() > 0) + .findFirst() + .orElseGet(() -> "arg" + i); + + return ResultsUtils.createParameter( + name, + value, + annotation.excluded(), + annotation.mode() + ); + }) + .collect(Collectors.toList()); + } + +} 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 c49cba794..6b5194826 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 @@ -64,8 +64,7 @@ "ClassDataAbstractionCoupling", "PMD.ExcessiveImports", "PMD.TooManyMethods", - "PMD.GodClass", - "deprecation" + "PMD.GodClass" }) public final class ResultsUtils { @@ -109,7 +108,16 @@ private ResultsUtils() { } public static Parameter createParameter(final String name, final Object value) { - return new Parameter().setName(name).setValue(ObjectUtils.toString(value)); + return createParameter(name, value, null, null); + } + + public static Parameter createParameter(final String name, final Object value, + final Boolean excluded, final Parameter.Mode mode) { + return new Parameter() + .setName(name) + .setValue(ObjectUtils.toString(value)) + .setExcluded(excluded) + .setMode(mode); } public static Label createSuiteLabel(final String suite) { @@ -353,7 +361,7 @@ private static String getRealHostName() { try { cachedHost = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException e) { - LOGGER.debug("Could not get host name {}", e); + LOGGER.debug("Could not get host name", e); cachedHost = "default"; } } diff --git a/allure-java-commons/src/test/java/io/qameta/allure/AllureTest.java b/allure-java-commons/src/test/java/io/qameta/allure/AllureTest.java index ac7dbccc9..9e874187c 100644 --- a/allure-java-commons/src/test/java/io/qameta/allure/AllureTest.java +++ b/allure-java-commons/src/test/java/io/qameta/allure/AllureTest.java @@ -180,6 +180,31 @@ void shouldAddParameter() { ); } + @Test + void shouldAddParameterWithModeAndExcluded() { + final Parameter first = current().nextObject(Parameter.class); + final Parameter second = current().nextObject(Parameter.class); + final Parameter third = current().nextObject(Parameter.class); + + final AllureResults results = runWithinTestContext( + () -> { + parameter(first.getName(), first.getValue(), first.getMode()); + parameter(second.getName(), second.getValue(), second.getExcluded()); + parameter(third.getName(), third.getValue(), third.getExcluded(), third.getMode()); + }, + Allure::setLifecycle + ); + + assertThat(results.getTestResults()) + .flatExtracting(TestResult::getParameters) + .extracting(Parameter::getName, Parameter::getValue, Parameter::getExcluded, Parameter::getMode) + .contains( + tuple(first.getName(), first.getValue(), null, first.getMode()), + tuple(second.getName(), second.getValue(), second.getExcluded(), null), + tuple(third.getName(), third.getValue(), third.getExcluded(), third.getMode()) + ); + } + @Test void shouldAddLinks() { final io.qameta.allure.model.Link first = current().nextObject(Link.class); diff --git a/allure-java-commons/src/test/java/io/qameta/allure/aspects/StepsAspectsTest.java b/allure-java-commons/src/test/java/io/qameta/allure/aspects/StepsAspectsTest.java index 72e3d2f5e..eb2cfb8c5 100644 --- a/allure-java-commons/src/test/java/io/qameta/allure/aspects/StepsAspectsTest.java +++ b/allure-java-commons/src/test/java/io/qameta/allure/aspects/StepsAspectsTest.java @@ -16,6 +16,7 @@ package io.qameta.allure.aspects; import io.qameta.allure.Issue; +import io.qameta.allure.Param; import io.qameta.allure.Step; import io.qameta.allure.model.Parameter; import io.qameta.allure.model.Status; @@ -30,6 +31,7 @@ import java.util.stream.Collectors; import static io.qameta.allure.test.RunUtils.runWithinTestContext; +import static io.qameta.allure.test.TestData.randomString; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; @@ -285,6 +287,35 @@ void shouldSupportParallelStepsRun() { ); } + @Test + void shouldProcessParamAnnotation() { + final String p1 = randomString(10); + final String p2 = randomString(10); + final String p3 = randomString(10); + final String p4 = randomString(10); + final AllureResults results = runWithinTestContext(() -> stepWithParamAnnotation(p1, p2, p3, p4)); + + assertThat(results.getTestResults()) + .flatExtracting(TestResult::getSteps) + .flatExtracting(StepResult::getParameters) + .extracting(Parameter::getName, Parameter::getValue, Parameter::getExcluded, Parameter::getMode) + .containsExactlyInAnyOrder( + tuple("Named", p1, false, Parameter.Mode.DEFAULT), + tuple("Excluded", p2, true, Parameter.Mode.DEFAULT), + tuple("Masked", p3, false, Parameter.Mode.MASKED), + tuple("Masked", p4, false, Parameter.Mode.HIDDEN) + ); + + } + + @Step + void stepWithParamAnnotation( + @Param("Named") final String named, + @Param(name = "Excluded", excluded = true) final String excluded, + @Param(name = "Masked", mode = Parameter.Mode.MASKED) final String masked, + @Param(name = "Masked", mode = Parameter.Mode.HIDDEN) final String hidden) { + } + @Step void stepWithDefaultName() { } diff --git a/allure-java-commons/src/test/java/io/qameta/allure/util/AspectUtilsTest.java b/allure-java-commons/src/test/java/io/qameta/allure/util/ObjectUtilsTest.java similarity index 98% rename from allure-java-commons/src/test/java/io/qameta/allure/util/AspectUtilsTest.java rename to allure-java-commons/src/test/java/io/qameta/allure/util/ObjectUtilsTest.java index ea5af2cde..64045ea81 100644 --- a/allure-java-commons/src/test/java/io/qameta/allure/util/AspectUtilsTest.java +++ b/allure-java-commons/src/test/java/io/qameta/allure/util/ObjectUtilsTest.java @@ -23,7 +23,7 @@ /** * @author charlie (Dmitry Baev). */ -class AspectUtilsTest { +class ObjectUtilsTest { @Issue("191") @Test From 447d3957d4413a31a5d7e7975d51a1d5408a912b Mon Sep 17 00:00:00 2001 From: Dmitry Baev Date: Fri, 3 Sep 2021 17:23:14 +0300 Subject: [PATCH 2/3] update test step context --- .../main/java/io/qameta/allure/Allure.java | 70 ++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/allure-java-commons/src/main/java/io/qameta/allure/Allure.java b/allure-java-commons/src/main/java/io/qameta/allure/Allure.java index bfe433f8e..fb7935036 100644 --- a/allure-java-commons/src/main/java/io/qameta/allure/Allure.java +++ b/allure-java-commons/src/main/java/io/qameta/allure/Allure.java @@ -535,10 +535,63 @@ public interface ThrowableContextRunnableVoid { */ public interface StepContext { + /** + * Sets step's name. + * + * @param name the deserted name of step. + */ void name(String name); + /** + * Adds parameter to a step. + * + * @param name the name of parameter. + * @param value the value. + * @param the type of value. + * @return the value. + */ T parameter(String name, T value); + /** + * Adds parameter to a step. + * + * @param name the name of parameter. + * @param value the value. + * @param excluded true if parameter should be excluded from history key generation, false otherwise. + * @param the type of value. + * @return the value. + */ + default T parameter(String name, T value, Boolean excluded) { + throw new UnsupportedOperationException("method is not implemented"); + } + + /** + * Adds parameter to a step. + * + * @param name the name of parameter. + * @param value the value. + * @param mode the parameter's mode. + * @param the type of value. + * @return the value. + */ + default T parameter(String name, T value, Parameter.Mode mode) { + throw new UnsupportedOperationException("method is not implemented"); + } + + /** + * Adds parameter to a step. + * + * @param name the name of parameter. + * @param value the value. + * @param excluded true if parameter should be excluded from history key generation, false otherwise. + * @param mode the parameter's mode. + * @param the type of value. + * @return the value. + */ + default T parameter(String name, T value, Boolean excluded, Parameter.Mode mode) { + throw new UnsupportedOperationException("method is not implemented"); + } + } /** @@ -559,7 +612,22 @@ public void name(final String name) { @Override public T parameter(final String name, final T value) { - final Parameter param = createParameter(name, value); + return parameter(name, value, null, null); + } + + @Override + public T parameter(final String name, final T value, final Boolean excluded) { + return parameter(name, value, excluded, null); + } + + @Override + public T parameter(final String name, final T value, final Parameter.Mode mode) { + return parameter(name, value, null, mode); + } + + @Override + public T parameter(final String name, final T value, final Boolean excluded, final Parameter.Mode mode) { + final Parameter param = createParameter(name, value, excluded, mode); getLifecycle().updateStep(uuid, stepResult -> stepResult.getParameters().add(param)); return value; } From 9995028287b9bee20a003ca8b3ba6df3c4c925aa Mon Sep 17 00:00:00 2001 From: Dmitry Baev Date: Mon, 13 Sep 2021 12:23:54 +0300 Subject: [PATCH 3/3] fix checkstyle --- allure-java-commons/src/main/java/io/qameta/allure/Allure.java | 1 + 1 file changed, 1 insertion(+) diff --git a/allure-java-commons/src/main/java/io/qameta/allure/Allure.java b/allure-java-commons/src/main/java/io/qameta/allure/Allure.java index fb7935036..90f069556 100644 --- a/allure-java-commons/src/main/java/io/qameta/allure/Allure.java +++ b/allure-java-commons/src/main/java/io/qameta/allure/Allure.java @@ -533,6 +533,7 @@ public interface ThrowableContextRunnableVoid { /** * Step context. */ + @SuppressWarnings("MultipleStringLiterals") public interface StepContext { /**