Skip to content

Commit

Permalink
@Ignore annotation support
Browse files Browse the repository at this point in the history
  • Loading branch information
HardNorth committed Nov 4, 2020
1 parent 65135b8 commit cf70074
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 30 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
### Added
- A test retry feature which is based on corresponding JunitFoundation's
[feature](https://github.com/sbabcoc/JUnit-Foundation#automatic-retry-of-failed-tests).
- `@Ignore` annotation support
### Changed
- JunitFoundation version was updated on 12.3.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
import com.epam.reportportal.service.item.TestCaseIdEntry;
import com.epam.reportportal.service.tree.TestItemTree;
import com.epam.reportportal.utils.AttributeParser;
import com.epam.reportportal.utils.ParameterUtils;
import com.epam.reportportal.utils.TestCaseIdUtils;
import com.epam.reportportal.utils.reflect.Accessible;
import com.epam.ta.reportportal.ws.model.*;
import com.epam.ta.reportportal.ws.model.attribute.ItemAttributesRQ;
import com.epam.ta.reportportal.ws.model.issue.Issue;
Expand All @@ -41,6 +43,9 @@
import org.junit.runners.Suite;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.TestClass;
import org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rp.com.google.common.annotations.VisibleForTesting;
import rp.com.google.common.base.Function;
import rp.com.google.common.base.Supplier;
Expand All @@ -49,9 +54,11 @@
import javax.annotation.Nullable;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import static com.epam.reportportal.junit.utils.ItemTreeUtils.createItemTreeKey;
import static java.util.Optional.ofNullable;
Expand All @@ -68,6 +75,8 @@
*/
public class ParallelRunningHandler implements IListenerHandler {

private static final Logger LOGGER = LoggerFactory.getLogger(ParallelRunningHandler.class);

private static final String FINISH_REQUEST = "FINISH_REQUEST";
private static final String START_TIME = "START_TIME";
private static final String IS_RETRY = "IS_RETRY";
Expand Down Expand Up @@ -364,9 +373,8 @@ public void handleTestSkip(AtomicTest<FrameworkMethod> testContext) {
TestItemTree.TestItemLeaf testLeaf = ofNullable(retrieveLeaf(runner)).orElseGet(() -> context.getItemTree()
.getTestItems()
.get(myParentKey));
TestItemTree.ItemTreeKey myKey = createItemTreeKey(method,
createStepParameters(testContext.getIdentity(), testContext.getRunner())
);
List<ParameterResource> parameters = createStepParameters(testContext.getIdentity(), testContext.getRunner());
TestItemTree.ItemTreeKey myKey = createItemTreeKey(method, parameters);

ofNullable(testLeaf).ifPresent(p -> {
TestItemTree.TestItemLeaf myLeaf = ofNullable(p.getChildItems().get(myKey)).orElse(null);
Expand Down Expand Up @@ -557,7 +565,12 @@ protected StartTestItemRQ buildStartStepRq(Object runner, Description descriptio
rq.setAttributes(getAttributes(method));
rq.setDescription(createStepDescription(description, method));
rq.setParameters(createStepParameters(method, runner));
rq.setTestCaseId(getTestCaseId(method, runner, rq.getCodeRef()).getId());
rq.setTestCaseId(ofNullable(getTestCaseId(
method,
rq.getCodeRef(),
ofNullable(rq.getParameters()).map(p -> p.stream().map(ParameterResource::getValue).collect(Collectors.toList()))
.orElse(null)
)).map(TestCaseIdEntry::getId).orElse(null));
rq.setStartTime(startTime);
MethodType type = MethodType.detect(method);
rq.setType(type == null ? "" : type.name());
Expand Down Expand Up @@ -611,6 +624,11 @@ protected FinishTestItemRQ buildFinishStepRq(@Nullable FrameworkMethod method, @
return rq;
}

protected <T> TestCaseIdEntry getTestCaseId(FrameworkMethod frameworkMethod, String codeRef, List<T> params) {
Method method = frameworkMethod.getMethod();
return TestCaseIdUtils.getTestCaseId(method.getAnnotation(TestCaseId.class), method, codeRef, params);
}

/**
* Extension point to customize Report Portal test parameters
*
Expand All @@ -623,19 +641,6 @@ protected List<ParameterResource> createStepParameters(FrameworkMethod method, O
return parameters.isEmpty() ? null : parameters;
}

protected TestCaseIdEntry getTestCaseId(FrameworkMethod method, Object runner, String codeRef) {
Object target = getTargetForRunner(runner);
return getTestCaseId(method.getMethod(), target, codeRef);
}

protected TestCaseIdEntry getTestCaseId(Method method, Object target, String codeRef) {
List<Object> params = null;
if (target instanceof ArtifactParams) {
params = ((ArtifactParams) target).getParameters().transform(p -> new ArrayList<>(p.values())).orNull();
}
return TestCaseIdUtils.getTestCaseId(method.getAnnotation(TestCaseId.class), method, codeRef, params);
}

/**
* Assemble execution parameters list for the specified framework method.
* <p>
Expand All @@ -649,7 +654,7 @@ protected TestCaseIdEntry getTestCaseId(Method method, Object target, String cod
@SuppressWarnings("squid:S3655")
private List<ParameterResource> createMethodParameters(FrameworkMethod method, Object runner) {
List<ParameterResource> result = new ArrayList<>();
if (!(method.isStatic() || isIgnored(method))) {
if (!(method.isStatic())) {
Object target = getTargetForRunner(runner);
if (target instanceof ArtifactParams) {
com.google.common.base.Optional<Map<String, Object>> params = ((ArtifactParams) target).getParameters();
Expand All @@ -661,6 +666,18 @@ private List<ParameterResource> createMethodParameters(FrameworkMethod method, O
result.add(parameter);
}
}
} else if (runner instanceof BlockJUnit4ClassRunnerWithParameters) {
try {
Optional<Constructor<?>> constructor = Arrays.stream(method.getDeclaringClass().getConstructors()).findFirst();
if (constructor.isPresent()) {
result.addAll(ParameterUtils.getParameters(constructor.get(),
Arrays.asList((Object[]) Accessible.on(runner).field("parameters").getValue())
));
}
} catch (NoSuchFieldException e) {
LOGGER.warn("Unable to get parameters for parameterized runner", e);
}

}
}
return result;
Expand Down Expand Up @@ -690,16 +707,6 @@ protected String createStepDescription(Description description, FrameworkMethod
return (itemDisplayName != null) ? itemDisplayName.value() : description.getDisplayName();
}

/**
* Determine if the specified JUnit framework method is being ignored.
*
* @param method JUnit framework method context
* @return {@code true} if specified method is being ignored; otherwise {@code false}
*/
private static boolean isIgnored(FrameworkMethod method) {
return (null != method.getAnnotation(Ignore.class));
}

/**
* Get name associated with the specified JUnit runner.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright 2020 EPAM Systems
*
* 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 com.epam.reportportal.junit.features.skip;

import com.epam.reportportal.annotations.ParameterKey;
import com.google.common.base.Optional;
import com.nordstrom.automation.junit.ArtifactParams;
import com.nordstrom.automation.junit.AtomIdentity;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import java.util.Collections;
import java.util.Map;

@RunWith(Parameterized.class)
public class ParameterizedIgnoredTest implements ArtifactParams {

@Rule
public final AtomIdentity identity = new AtomIdentity(this);

@Parameters
public static Object[] params() {
return new Object[] { "one", "two, three" };
}

private final String parameter;

public ParameterizedIgnoredTest(@ParameterKey("param") String param) {
parameter = param;
}

@Test
@Ignore
public void testParameters() {
System.out.println("Parameter test: " + parameter);
}

@Override
public AtomIdentity getAtomIdentity() {
return identity;
}

@Override
public Description getDescription() {
return identity.getDescription();
}

@Override
public Optional<Map<String, Object>> getParameters() {
return Optional.of(Collections.singletonMap("param", parameter));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2020 EPAM Systems
*
* 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 com.epam.reportportal.junit.ignore;

import com.epam.reportportal.junit.ParallelRunningHandler;
import com.epam.reportportal.junit.features.skip.IgnoredTest;
import com.epam.reportportal.junit.utils.TestUtils;
import com.epam.reportportal.listeners.ItemStatus;
import com.epam.reportportal.service.ReportPortal;
import com.epam.reportportal.service.ReportPortalClient;
import com.epam.reportportal.util.test.CommonUtils;
import com.epam.ta.reportportal.ws.model.FinishTestItemRQ;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.*;

public class BasicIgnoreTest {

private final String launchId = CommonUtils.namedId("launch_");
private final String suiteId = CommonUtils.namedId("suite_");
private final String classId = CommonUtils.namedId("class_");
private final String methodId = CommonUtils.namedId("method_");

private final ReportPortalClient client = mock(ReportPortalClient.class);

@BeforeEach
public void setupMock() {
TestUtils.mockLaunch(client, launchId, suiteId, classId, methodId);
TestUtils.mockLogging(client);
ParallelRunningHandler.setReportPortal(ReportPortal.create(client, TestUtils.standardParameters()));
}

@Test
public void verify_an_ignored_test_reporting() {
TestUtils.runClasses(IgnoredTest.class);

verify(client, times(1)).startTestItem(any());
verify(client, times(1)).startTestItem(same(suiteId), any());
ArgumentCaptor<FinishTestItemRQ> finishCaptor = ArgumentCaptor.forClass(FinishTestItemRQ.class);
verify(client, times(1)).startTestItem(same(classId), any());
verify(client, times(1)).finishTestItem(same(methodId), finishCaptor.capture());

FinishTestItemRQ finishRq = finishCaptor.getValue();

assertThat(finishRq.getStatus(), allOf(notNullValue(), equalTo(ItemStatus.SKIPPED.name())));
assertThat(finishRq.getIssue(), nullValue());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright 2020 EPAM Systems
*
* 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 com.epam.reportportal.junit.ignore;

import com.epam.reportportal.junit.ParallelRunningHandler;
import com.epam.reportportal.junit.features.skip.ParameterizedIgnoredTest;
import com.epam.reportportal.junit.utils.TestUtils;
import com.epam.reportportal.listeners.ItemStatus;
import com.epam.reportportal.service.ReportPortal;
import com.epam.reportportal.service.ReportPortalClient;
import com.epam.reportportal.util.test.CommonUtils;
import com.epam.ta.reportportal.ws.model.FinishTestItemRQ;
import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;

public class IgnoreParameterizedTest {

private final String launchId = CommonUtils.namedId("launch_");
private final String suiteId = CommonUtils.namedId("suite_");
private final String classId = CommonUtils.namedId("class_");
private final List<String> methodIds = Stream.generate(() -> CommonUtils.namedId("method_")).limit(2).collect(Collectors.toList());

private final ReportPortalClient client = mock(ReportPortalClient.class);

@BeforeEach
public void setupMock() {
TestUtils.mockLaunch(client, launchId, suiteId, classId, methodIds);
TestUtils.mockLogging(client);
ParallelRunningHandler.setReportPortal(ReportPortal.create(client, TestUtils.standardParameters()));
}

@Test
public void verify_a_test_with_one_retry() {
TestUtils.runClasses(ParameterizedIgnoredTest.class);

verify(client, times(1)).startTestItem(any());
ArgumentCaptor<StartTestItemRQ> startCaptor = ArgumentCaptor.forClass(StartTestItemRQ.class);
ArgumentCaptor<FinishTestItemRQ> finishCaptor = ArgumentCaptor.forClass(FinishTestItemRQ.class);
verify(client, times(1)).startTestItem(same(suiteId), any());
verify(client, times(2)).startTestItem(same(classId), startCaptor.capture());
verify(client, times(1)).finishTestItem(same(methodIds.get(0)), finishCaptor.capture());
verify(client, times(1)).finishTestItem(same(methodIds.get(1)), finishCaptor.capture());

List<StartTestItemRQ> startRqs = startCaptor.getAllValues();
assertThat(startRqs.get(0).getTestCaseId(), not(equalTo(startRqs.get(1).getTestCaseId()))); // test case ID should be parameterized
assertThat(startRqs.get(0).getParameters(), allOf(notNullValue(), hasSize(1)));
assertThat(startRqs.get(1).getParameters(), allOf(notNullValue(), hasSize(1)));
assertThat(startRqs.get(0).getCodeRef(), equalTo(startRqs.get(1).getCodeRef()));

finishCaptor.getAllValues().forEach(i -> {
assertThat(i.getIssue(), nullValue());
assertThat(i.getStatus(), equalTo(ItemStatus.SKIPPED.name()));
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public void setupMock() {
}

@Test
public void verify_static_test_code_reference_generation() {
public void verify_a_test_with_one_retry() {
TestUtils.runClasses(BasicRetryPassedTest.class);

verify(client, times(1)).startTestItem(any());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public void setupMock() {
}

@Test
public void verify_static_test_code_reference_generation() {
public void verify_a_parameterized_test_with_one_retry_for_the_first_parameter() {
TestUtils.runClasses(StandardParametersRetryTest.class);

verify(client, times(1)).startTestItem(any());
Expand Down

0 comments on commit cf70074

Please sign in to comment.