Skip to content

Commit

Permalink
improve testng parameters processing (via allure-framework#326)
Browse files Browse the repository at this point in the history
  • Loading branch information
baev authored Feb 12, 2019
1 parent dbb6ac0 commit 22a1de6
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 45,17 @@
import org.testng.ITestListener;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.annotations.Parameters;
import org.testng.internal.ConstructorOrMethod;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;

import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -84,11 85,9 @@
import static io.qameta.allure.util.ResultsUtils.getProvidedLabels;
import static io.qameta.allure.util.ResultsUtils.getStatusDetails;
import static io.qameta.allure.util.ResultsUtils.processDescription;
import static java.lang.Math.min;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Comparator.comparing;
import static java.util.Objects.nonNull;
import static java.util.stream.IntStream.range;

/**
* Allure TestNG listener.
Expand Down Expand Up @@ -129,6 128,10 @@ public class AllureTestNg implements
private final Map<ITestClass, String> classContainerUuidStorage = new ConcurrentHashMap<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();

private static final List<Class<?>> INJECTED_TYPES = Arrays.asList(
ITestContext.class, ITestResult.class, XmlTest.class, Method.class, Object[].class
);

private final AllureLifecycle lifecycle;

public AllureTestNg(final AllureLifecycle lifecycle) {
Expand Down Expand Up @@ -638,24 641,48 @@ private static String safeExtractTestClassName(final ITestClass testClass) {
private List<Parameter> getParameters(final ITestContext context,
final ITestNGMethod method,
final Object... parameters) {
final Stream<Parameter> tagsParameters = context
.getCurrentXmlTest().getAllParameters().entrySet()
.stream()
.map(entry -> createParameter(entry.getKey(), entry.getValue()));
final String[] parameterNames = getMethod(method)
.map(Executable::getParameters)
.map(Stream::of)
.orElseGet(Stream::empty)
.map(java.lang.reflect.Parameter::getName)
.toArray(String[]::new);
final String[] parameterValues = nonNull(parameters)
? Stream.of(parameters)
.map(ObjectUtils::toString)
.toArray(String[]::new)
: new String[]{};
final Stream<Parameter> methodParameters = range(0, min(parameterNames.length, parameterValues.length))
.mapToObj(i -> createParameter(parameterNames[i], parameterValues[i]));
return Stream.concat(tagsParameters, methodParameters)
final Map<String, String> result = new HashMap<>(
context.getCurrentXmlTest().getAllParameters()
);

getMethod(method).ifPresent(m -> {
final Class<?>[] parameterTypes = m.getParameterTypes();

if (parameterTypes.length != parameters.length) {
return;
}

final String[] providedNames = Optional.ofNullable(m.getAnnotation(Parameters.class))
.map(Parameters::value)
.orElse(new String[]{});

final String[] reflectionNames = Stream.of(m.getParameters())
.map(java.lang.reflect.Parameter::getName)
.toArray(String[]::new);

int skippedCount = 0;
for (int i = 0; i < parameterTypes.length; i ) {
final Class<?> parameterType = parameterTypes[i];
if (INJECTED_TYPES.contains(parameterType)) {
skippedCount ;
continue;
}

final int indexFromAnnotation = i - skippedCount;
if (indexFromAnnotation < providedNames.length) {
result.put(providedNames[indexFromAnnotation], ObjectUtils.toString(parameters[i]));
continue;
}

if (i < reflectionNames.length) {
result.put(reflectionNames[i], ObjectUtils.toString(parameters[i]));
}
}

});

return result.entrySet().stream()
.map(entry -> createParameter(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1019,8 1019,8 @@ public void shouldNotFailForNullParameters() {
assertThat(results.getTestResults())
.flatExtracting(TestResult::getParameters)
.extracting(Parameter::getName, Parameter::getValue)
.containsExactly(
tuple("arg0", "null")
.containsExactlyInAnyOrder(
tuple("param", "null")
);
}

Expand All @@ -1034,10 1034,10 @@ public void shouldProcessArrayParameters() {
assertThat(results.getTestResults())
.flatExtracting(TestResult::getParameters)
.extracting(Parameter::getName, Parameter::getValue)
.containsExactly(
tuple("arg0", "a"),
tuple("arg1", "false"),
tuple("arg2", "[1, 2, 3]")
.containsExactlyInAnyOrder(
tuple("first", "a"),
tuple("second", "false"),
tuple("third", "[1, 2, 3]")
);
}

Expand Down Expand Up @@ -1067,6 1067,21 @@ public void shouldProcessFailedSetUps(final XmlSuite.ParallelMode mode, final in
);
}

@SuppressWarnings("unchecked")
@AllureFeatures.Parameters
@Test
public void shouldOverrideParameters() {
final AllureResults results = runTestNgSuites("suites/parameters-override.xml");

assertThat(results.getTestResults())
.flatExtracting(TestResult::getParameters)
.extracting(Parameter::getName, Parameter::getValue)
.containsExactlyInAnyOrder(
tuple("first", "first-test"),
tuple("second", "second-test")
);
}

private AllureResults runTestNgSuites(final String... suites) {
final Consumer<TestNG> emptyConfigurer = testNg -> {
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 1,36 @@
/*
* 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.testng.samples;

import org.testng.ITestContext;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import java.lang.reflect.Method;

/**
* @author charlie (Dmitry Baev).
*/
public class TestWithParameters {

@Parameters({"first", "second"})
@Test
public void test(final Method method,
final String first,
final ITestContext context,
final String s) {
}
}
14 changes: 14 additions & 0 deletions allure-testng/src/test/resources/suites/parameters-override.xml
Original file line number Diff line number Diff line change
@@ -0,0 1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >

<suite name="Github Issues">
<parameter name="first" value="first-suite"/>
<parameter name="second" value="second-suite"/>
<test name="gh-219">
<parameter name="first" value="first-test"/>
<parameter name="second" value="second-test"/>
<classes>
<class name="io.qameta.allure.testng.samples.TestWithParameters"/>
</classes>
</test>
</suite>
5 changes: 5 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 108,11 @@ configure(subprojects) {
}
}

tasks.withType(JavaCompile::class) {
options.encoding = "UTF-8"
options.compilerArgs.add("-parameters")
}

tasks.named<Jar>("jar") {
manifest {
attributes(mapOf(
Expand Down

0 comments on commit 22a1de6

Please sign in to comment.