Skip to content

Commit

Permalink
Merge pull request #125 from oleksandr-fomenko/RPP_Agents_Java_JUnit_…
Browse files Browse the repository at this point in the history
…Annotation_Description

Added support of the @description annotation
  • Loading branch information
HardNorth authored Mar 27, 2024
2 parents e10f477 + 2e8f16e commit 84d61de
Show file tree
Hide file tree
Showing 9 changed files with 300 additions and 7 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ repositories {
}

dependencies {
api 'com.epam.reportportal:client-java:5.2.5'
api 'com.epam.reportportal:client-java:5.2.6'

compileOnly "org.junit.jupiter:junit-jupiter-api:${junit_version}"
implementation 'com.google.code.findbugs:jsr305:3.0.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.epam.reportportal.junit5;

import com.epam.reportportal.annotations.Description;
import com.epam.reportportal.annotations.ParameterKey;
import com.epam.reportportal.annotations.TestCaseId;
import com.epam.reportportal.annotations.attribute.Attributes;
Expand Down Expand Up @@ -350,8 +351,9 @@ public void afterTestExecution(ExtensionContext context) {
@Override
public void testDisabled(ExtensionContext context, Optional<String> reason) {
if (Boolean.parseBoolean(System.getProperty("reportDisabledTests"))) {
String description = reason.orElse(createStepDescription(context));
startTestItem(context, Collections.emptyList(), STEP, description, Calendar.getInstance().getTime());
final ItemType itemType = STEP;
String description = reason.orElse(createStepDescription(context, itemType));
startTestItem(context, Collections.emptyList(), itemType, description, Calendar.getInstance().getTime());
finishTest(context, SKIPPED);
}
}
Expand Down Expand Up @@ -455,7 +457,7 @@ protected void startTestItem(ExtensionContext context, ItemType type) {
* @param type a type of the item
*/
protected void startTestItem(ExtensionContext context, List<Object> arguments, ItemType type) {
startTestItem(context, arguments, type, createStepDescription(context), Calendar.getInstance().getTime());
startTestItem(context, arguments, type, createStepDescription(context, type), Calendar.getInstance().getTime());
}

/**
Expand Down Expand Up @@ -822,8 +824,41 @@ protected String createConfigurationName(@Nonnull Class<?> testClass, @Nonnull M
* @return Test/Step Description being sent to ReportPortal
*/
@SuppressWarnings("unused")
protected String createStepDescription(ExtensionContext context) {
return "";
protected String createStepDescription(ExtensionContext context, final ItemType itemType) {
String defaultValue = "";
if (itemType != STEP) {
return defaultValue;
}
Optional<Method> optionalMethod = getOptionalTestMethod(context);
if (!optionalMethod.isPresent()){
return defaultValue;
}
Method method = optionalMethod.get();

Description descriptionFromMethod = method.getAnnotation(Description.class);
if(descriptionFromMethod != null){
return descriptionFromMethod.value();
}

Description descriptionFromClass = method.getDeclaringClass().getAnnotation(Description.class);
if(descriptionFromClass != null){
return descriptionFromClass.value();
}

return defaultValue;
}

private Optional<Method> getOptionalTestMethod(ExtensionContext context){
Optional<Method> optionalMethod = context.getTestMethod();
if(!optionalMethod.isPresent()){
//if not present means that we are in the dynamic test, in this case we need to move to the parent context
Optional<ExtensionContext> parentContext = context.getParent();
if(!parentContext.isPresent()){
return Optional.empty();
}
return parentContext.get().getTestMethod();
}
return optionalMethod;
}

/**
Expand Down Expand Up @@ -853,7 +888,8 @@ protected void reportSkippedStep(ReflectiveInvocationContext<Method> invocationC
// to fix item ordering when @AfterEach starts in the same millisecond as skipped test
skipStartTime = new Date(skipStartTime.getTime() - 1);
}
startTestItem(context, invocationContext.getArguments(), STEP, createStepDescription(context), skipStartTime);
final ItemType itemType = STEP;
startTestItem(context, invocationContext.getArguments(), itemType, createStepDescription(context, itemType), skipStartTime);
createSkippedSteps(context, throwable);
FinishTestItemRQ finishRq = buildFinishTestItemRq(context, SKIPPED);
finishRq.setIssue(Launch.NOT_ISSUE);
Expand Down
148 changes: 148 additions & 0 deletions src/test/java/com/epam/reportportal/junit5/DescriptionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package com.epam.reportportal.junit5;

import com.epam.reportportal.junit5.features.description.*;
import com.epam.reportportal.junit5.util.TestUtils;
import com.epam.reportportal.service.Launch;
import com.epam.reportportal.util.test.CommonUtils;
import com.epam.ta.reportportal.ws.model.StartTestItemRQ;
import io.reactivex.Maybe;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.mockito.ArgumentCaptor;
import org.mockito.stubbing.Answer;

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

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

/**
* @author <a href="mailto:[email protected]">Oleksandr Fomenko</a>
*/
public class DescriptionTest {
public static class TestExtension extends ReportPortalExtension {
static Launch LAUNCH;

@Override
protected Launch getLaunch(ExtensionContext context) {
return LAUNCH;
}
}

@BeforeEach
public void setupMock() {
TestExtension.LAUNCH = mock(Launch.class);
when(TestExtension.LAUNCH.startTestItem(any())).thenAnswer((Answer<Maybe<String>>) invocation -> CommonUtils.createMaybeUuid());
when(TestExtension.LAUNCH.startTestItem(any(),
any()
)).thenAnswer((Answer<Maybe<String>>) invocation -> CommonUtils.createMaybeUuid());
}

@Test
void descriptionFromMethodAnnotationTest() {
TestUtils.runClasses(DescriptionAnnotatedMethodTest.class);

Launch launch = TestExtension.LAUNCH;

verify(launch, times(1)).startTestItem(any()); // Start parent Suite

ArgumentCaptor<StartTestItemRQ> captor = ArgumentCaptor.forClass(StartTestItemRQ.class);
verify(launch, times(1)).startTestItem(notNull(), captor.capture()); // Start a test

StartTestItemRQ request = captor.getValue();
assertThat(request.getDescription(), equalTo(DescriptionAnnotatedMethodTest.TEST_DESCRIPTION_METHOD));
}

@Test
void descriptionFromClassAnnotationTest() {
TestUtils.runClasses(DescriptionAnnotatedClassTest.class);

Launch launch = TestExtension.LAUNCH;

verify(launch, times(1)).startTestItem(any()); // Start parent Suite

ArgumentCaptor<StartTestItemRQ> captor = ArgumentCaptor.forClass(StartTestItemRQ.class);
verify(launch, times(1)).startTestItem(notNull(), captor.capture()); // Start a test

StartTestItemRQ request = captor.getValue();
assertThat(request.getDescription(), equalTo(DescriptionAnnotatedClassTest.TEST_DESCRIPTION_CLASS));
}

@Test
void descriptionFromBothMethodAndClassAnnotationTest() {
TestUtils.runClasses(DescriptionAnnotatedMethodAndClassTest.class);

Launch launch = TestExtension.LAUNCH;

verify(launch, times(1)).startTestItem(any()); // Start parent Suite

ArgumentCaptor<StartTestItemRQ> captor = ArgumentCaptor.forClass(StartTestItemRQ.class);
verify(launch, times(1)).startTestItem(notNull(), captor.capture()); // Start a test

StartTestItemRQ request = captor.getValue();
//from both annotations the expected one should be taken from the method
assertThat(request.getDescription(), equalTo(DescriptionAnnotatedMethodTest.TEST_DESCRIPTION_METHOD));
}

@Test
void descriptionFromMethodAnnotationDynamicTest() {
TestUtils.runClasses(DescriptionAnnotatedMethodDynamicTest.class);

Launch launch = TestExtension.LAUNCH;
verify(launch, times(1)).startTestItem(any()); // Start parent Suite

ArgumentCaptor<StartTestItemRQ> captor = ArgumentCaptor.forClass(StartTestItemRQ.class);
verify(launch, times(2)).startTestItem(notNull(), captor.capture()); // Start a test

List<String> testStepsDescription = captor.getAllValues()
.stream()
.filter(e -> e.getType().equals(ItemType.STEP.name()))
.map(StartTestItemRQ::getDescription)
.collect(Collectors.toList());

assertThat(testStepsDescription, hasItem(DescriptionAnnotatedMethodDynamicTest.TEST_DESCRIPTION_DYNAMIC_METHOD));
}

@Test
void descriptionFromClassAnnotationDynamicTest() {
TestUtils.runClasses(DescriptionAnnotatedClassDynamicTest.class);

Launch launch = TestExtension.LAUNCH;
verify(launch, times(1)).startTestItem(any()); // Start parent Suite

ArgumentCaptor<StartTestItemRQ> captor = ArgumentCaptor.forClass(StartTestItemRQ.class);
verify(launch, times(2)).startTestItem(notNull(), captor.capture()); // Start a test

List<String> testStepsDescription = captor.getAllValues()
.stream()
.filter(e -> e.getType().equals(ItemType.STEP.name()))
.map(StartTestItemRQ::getDescription)
.collect(Collectors.toList());

assertThat(testStepsDescription, hasItem(DescriptionAnnotatedClassDynamicTest.TEST_DESCRIPTION_DYNAMIC_CLASS));
}

@Test
void descriptionFromBothMethodAndClassAnnotationDynamicTest() {
TestUtils.runClasses(DescriptionAnnotatedMethodAndClassDynamicTest.class);

Launch launch = TestExtension.LAUNCH;
verify(launch, times(1)).startTestItem(any()); // Start parent Suite

ArgumentCaptor<StartTestItemRQ> captor = ArgumentCaptor.forClass(StartTestItemRQ.class);
verify(launch, times(2)).startTestItem(notNull(), captor.capture()); // Start a test

List<String> testStepsDescription = captor.getAllValues()
.stream()
.filter(e -> e.getType().equals(ItemType.STEP.name()))
.map(StartTestItemRQ::getDescription)
.collect(Collectors.toList());
//from both annotations the expected one should be taken from the method
assertThat(testStepsDescription, hasItem(DescriptionAnnotatedMethodDynamicTest.TEST_DESCRIPTION_DYNAMIC_METHOD));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.epam.reportportal.junit5.features.description;

import com.epam.reportportal.annotations.Description;
import com.epam.reportportal.junit5.DescriptionTest;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.extension.ExtendWith;

import java.util.stream.Stream;

import static org.junit.jupiter.api.DynamicTest.dynamicTest;

@ExtendWith(DescriptionTest.TestExtension.class)
@Description(DescriptionAnnotatedClassDynamicTest.TEST_DESCRIPTION_DYNAMIC_CLASS)
public class DescriptionAnnotatedClassDynamicTest {
public static final String TEST_DESCRIPTION_DYNAMIC_CLASS = "My test description on the dynamic class";
@TestFactory

Stream<DynamicTest> testForTestFactory() {
return Stream.of(dynamicTest("My dynamic test", () -> System.out.println("Inside dynamic test")));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.epam.reportportal.junit5.features.description;

import com.epam.reportportal.annotations.Description;
import com.epam.reportportal.junit5.DescriptionTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@Description(DescriptionAnnotatedClassTest.TEST_DESCRIPTION_CLASS)
@ExtendWith(DescriptionTest.TestExtension.class)
public class DescriptionAnnotatedClassTest {
public static final String TEST_DESCRIPTION_CLASS = "My test description on the class";
@Test
public void testDescriptionTest() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.epam.reportportal.junit5.features.description;

import com.epam.reportportal.annotations.Description;
import com.epam.reportportal.junit5.DescriptionTest;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.extension.ExtendWith;

import java.util.stream.Stream;

import static org.junit.jupiter.api.DynamicTest.dynamicTest;

@ExtendWith(DescriptionTest.TestExtension.class)
@Description(DescriptionAnnotatedClassDynamicTest.TEST_DESCRIPTION_DYNAMIC_CLASS)
public class DescriptionAnnotatedMethodAndClassDynamicTest {
@TestFactory
@Description(DescriptionAnnotatedMethodDynamicTest.TEST_DESCRIPTION_DYNAMIC_METHOD)
Stream<DynamicTest> testForTestFactory() {
return Stream.of(dynamicTest("My dynamic test", () -> System.out.println("Inside dynamic test")));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.epam.reportportal.junit5.features.description;

import com.epam.reportportal.annotations.Description;
import com.epam.reportportal.junit5.DescriptionTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(DescriptionTest.TestExtension.class)
@Description(DescriptionAnnotatedClassTest.TEST_DESCRIPTION_CLASS)
public class DescriptionAnnotatedMethodAndClassTest {
@Test
@Description(DescriptionAnnotatedMethodTest.TEST_DESCRIPTION_METHOD)
public void testDescriptionTest() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.epam.reportportal.junit5.features.description;

import com.epam.reportportal.annotations.Description;
import com.epam.reportportal.junit5.DescriptionTest;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.extension.ExtendWith;

import java.util.stream.Stream;

import static org.junit.jupiter.api.DynamicTest.dynamicTest;

@ExtendWith(DescriptionTest.TestExtension.class)
public class DescriptionAnnotatedMethodDynamicTest {
public static final String TEST_DESCRIPTION_DYNAMIC_METHOD = "My test description on the dynamic method";
@TestFactory
@Description(TEST_DESCRIPTION_DYNAMIC_METHOD)
Stream<DynamicTest> testForTestFactory() {
return Stream.of(dynamicTest("My dynamic test", () -> System.out.println("Inside dynamic test")));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.epam.reportportal.junit5.features.description;

import com.epam.reportportal.annotations.Description;
import com.epam.reportportal.junit5.DescriptionTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(DescriptionTest.TestExtension.class)
public class DescriptionAnnotatedMethodTest {
public static final String TEST_DESCRIPTION_METHOD = "My test description on the method";
@Test
@Description(TEST_DESCRIPTION_METHOD)
public void testDescriptionTest() {
}
}

0 comments on commit 84d61de

Please sign in to comment.