Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release #212

Merged
merged 9 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
java-version: '11'

- name: Setup git credentials
uses: oleksiyrudenko/gha-git-credentials@v2.1.1
uses: oleksiyrudenko/gha-git-credentials@v2-latest
with:
name: 'reportportal.io'
email: 'support@reportportal.io'
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Changelog

## [Unreleased]
### Changed
- Client version updated on [5.2.15](https://github.com/reportportal/client-java/releases/tag/5.2.15), by @HardNorth
- Format of last error log of test in item description was updated, by @HardNorth
### Removed
- Code reference report on Test NG's "Test" level to address issues with reruns, by @HardNorth

## [5.4.2]
### Added
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ repositories {
}

dependencies {
api 'com.epam.reportportal:client-java:5.2.13'
api 'com.epam.reportportal:client-java:5.2.15'

compileOnly "org.testng:testng:${testng_version}"
implementation 'org.slf4j:slf4j-api:2.0.4'
Expand All @@ -62,7 +62,7 @@ dependencies {

testImplementation 'com.epam.reportportal:logger-java-logback:5.2.2'

testImplementation 'org.apache.commons:commons-io:1.3.2'
testImplementation 'commons-io:commons-io:2.17.0'
testImplementation 'com.ibm.icu:icu4j:67.1'
testImplementation ('com.google.inject:guice:5.1.0') {
exclude module: 'guava'
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description=TestNG integration for ReportPortal
junit5_version=5.6.3
junit5_runner_version=1.6.3
mockito_version=3.3.3
testng_version=7.9.0
testng_version=7.10.2
scripts_url=https://raw.githubusercontent.com/reportportal/gradle-scripts
scripts_branch=master
excludeTests=
52 changes: 26 additions & 26 deletions src/main/java/com/epam/reportportal/testng/TestNGService.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@
import com.epam.reportportal.utils.MemoizingSupplier;
import com.epam.reportportal.utils.ParameterUtils;
import com.epam.reportportal.utils.TestCaseIdUtils;
import com.epam.reportportal.utils.markdown.MarkdownUtils;
import com.epam.reportportal.utils.properties.SystemAttributesExtractor;
import com.epam.ta.reportportal.ws.model.*;
import com.epam.ta.reportportal.ws.model.attribute.ItemAttributesRQ;
import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
import io.reactivex.Maybe;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.testng.*;
Expand Down Expand Up @@ -73,16 +75,14 @@
* TestNG service implements operations for interaction ReportPortal
*/
public class TestNGService implements ITestNGService {
private static final Set<TestMethodType> BEFORE_METHODS = Stream.of(
TestMethodType.BEFORE_TEST,
private static final Set<TestMethodType> BEFORE_METHODS = Stream.of(TestMethodType.BEFORE_TEST,
TestMethodType.BEFORE_SUITE,
TestMethodType.BEFORE_GROUPS,
TestMethodType.BEFORE_CLASS,
TestMethodType.BEFORE_METHOD
).collect(Collectors.toSet());
private static final String AGENT_PROPERTIES_FILE = "agent.properties";
private static final Set<String> TESTNG_INVOKERS = Stream.of(
"org.testng.internal.TestInvoker",
private static final Set<String> TESTNG_INVOKERS = Stream.of("org.testng.internal.TestInvoker",
"org.testng.internal.invokers.TestInvoker"
).collect(Collectors.toSet());
private static final Predicate<StackTraceElement> IS_RETRY_ELEMENT = e -> TESTNG_INVOKERS.contains(e.getClassName())
Expand All @@ -95,7 +95,7 @@ public class TestNGService implements ITestNGService {
public static final String RP_RETRY = "rp_retry";
public static final String RP_METHOD_TYPE = "rp_method_type";
public static final String NULL_VALUE = "NULL";
public static final String DESCRIPTION_ERROR_FORMAT = "%s\nError: \n%s";
public static final String DESCRIPTION_ERROR_FORMAT = "Error: \n%s";
public static final TestItemTree ITEM_TREE = new TestItemTree();

private final Map<Object, Queue<Pair<Maybe<String>, FinishTestItemRQ>>> BEFORE_METHOD_TRACKER = new ConcurrentHashMap<>();
Expand Down Expand Up @@ -282,7 +282,7 @@ protected StartTestItemRQ buildStartConfigurationRq(@Nonnull ITestResult testRes

@Override
public void startConfiguration(ITestResult testResult) {
if(ofNullable(getAttribute(testResult, RP_ID)).isPresent()) {
if (ofNullable(getAttribute(testResult, RP_ID)).isPresent()) {
// Already started, E.G. SkipException is thrown
return;
}
Expand Down Expand Up @@ -469,13 +469,11 @@ public void finishTestMethod(ItemStatus status, ITestResult testResult) {
if (ItemStatus.FAILED == status && (TestMethodType.BEFORE_METHOD == type || TestMethodType.BEFORE_CLASS == type)) {
SKIPPED_STATUS_TRACKER.put(instance, Boolean.TRUE);
}
if (ItemStatus.SKIPPED == status
&& (SKIPPED_STATUS_TRACKER.containsKey(instance)
|| (TestMethodType.BEFORE_METHOD == type && getAttribute(testResult, RP_RETRY) != null))
) {
if (ItemStatus.SKIPPED == status && (SKIPPED_STATUS_TRACKER.containsKey(instance) || (TestMethodType.BEFORE_METHOD == type
&& getAttribute(testResult, RP_RETRY) != null))) {
rq.setIssue(Launch.NOT_ISSUE);
}
if(ItemStatus.SKIPPED == status && BEFORE_METHODS.contains(type) && testResult.getThrowable() != null) {
if (ItemStatus.SKIPPED == status && BEFORE_METHODS.contains(type) && testResult.getThrowable() != null) {
sendReportPortalMsg(testResult);
SKIPPED_STATUS_TRACKER.put(instance, Boolean.TRUE);
}
Expand Down Expand Up @@ -531,13 +529,9 @@ protected StartTestItemRQ buildStartTestItemRq(@Nonnull ITestContext testContext
StartTestItemRQ rq = new StartTestItemRQ();
Set<ItemAttributesRQ> attributes = rq.getAttributes() == null ? new HashSet<>() : new HashSet<>(rq.getAttributes());
rq.setAttributes(attributes);
ofNullable(testContext.getCurrentXmlTest()).map(XmlTest::getXmlClasses).ifPresent(xmlClasses -> xmlClasses.forEach(xmlClass -> {
String className = xmlClass.getName();
String codeRef = rq.getCodeRef();
rq.setCodeRef(codeRef == null ? className : codeRef + ";" + className);
ofNullable(xmlClass.getSupportClass()).map(c -> c.getAnnotation(Attributes.class))
.ifPresent(a -> attributes.addAll(AttributeParser.retrieveAttributes(a)));
}));
ofNullable(testContext.getCurrentXmlTest()).map(XmlTest::getXmlClasses)
.ifPresent(xmlClasses -> xmlClasses.forEach(xmlClass -> ofNullable(xmlClass.getSupportClass()).map(c -> c.getAnnotation(
Attributes.class)).ifPresent(a -> attributes.addAll(AttributeParser.retrieveAttributes(a)))));
rq.setName(testContext.getName());
rq.setStartTime(testContext.getStartDate());
rq.setType("TEST");
Expand Down Expand Up @@ -717,7 +711,7 @@ protected String createConfigurationDescription(ITestResult testResult) {
*/
protected String createStepName(ITestResult testResult) {
var methodDisplayNameOptional = getMethodAnnotation(DisplayName.class, testResult);
if(methodDisplayNameOptional.isPresent()){
if (methodDisplayNameOptional.isPresent()) {
return methodDisplayNameOptional.get().value();
}
String testStepName = testResult.getTestName();
Expand All @@ -732,7 +726,7 @@ protected String createStepName(ITestResult testResult) {
*/
protected String createStepDescription(ITestResult testResult) {
var methodDescriptionOptional = getMethodAnnotation(Description.class, testResult);
if(methodDescriptionOptional.isPresent()){
if (methodDescriptionOptional.isPresent()) {
return methodDescriptionOptional.get().value();
}
return testResult.getMethod().getDescription();
Expand All @@ -745,8 +739,13 @@ private TestCaseIdEntry getTestCaseId(@Nonnull String codeRef, @Nonnull ITestRes
List<Object> parameters = ofNullable(testResult.getParameters()).map(Arrays::asList).orElse(null);
TestCaseIdEntry id = getMethodAnnotation(TestCaseId.class,
testResult
).flatMap(a -> ofNullable(method).map(m -> TestCaseIdUtils.getTestCaseId(a, m, codeRef, parameters, instance)))
.orElse(TestCaseIdUtils.getTestCaseId(codeRef, parameters));
).flatMap(a -> ofNullable(method).map(m -> TestCaseIdUtils.getTestCaseId(
a,
m,
codeRef,
parameters,
instance
))).orElse(TestCaseIdUtils.getTestCaseId(codeRef, parameters));

return id == null ? null : id.getId().endsWith("[]") ? new TestCaseIdEntry(id.getId().substring(0, id.getId().length() - 2)) : id;
}
Expand Down Expand Up @@ -805,13 +804,14 @@ Maybe<String> getConfigParent(ITestResult testResult, TestMethodType type) {

/**
* Extension point to customize test step description with error message
*
* @param testResult TestNG's testResult context
* @return Test/Step Description being sent to ReportPortal
*/
private String getLogMessage(ITestResult testResult) {
return String.format(DESCRIPTION_ERROR_FORMAT,
createStepDescription(testResult),
ExceptionUtils.getStackTrace(testResult.getThrowable()))
.trim();
String error = String.format(DESCRIPTION_ERROR_FORMAT, ExceptionUtils.getStackTrace(testResult.getThrowable())).trim();
return ofNullable(createStepDescription(testResult)).filter(StringUtils::isNotBlank)
.map(description -> MarkdownUtils.asTwoParts(description, error))
.orElse(error);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.epam.reportportal.service.ReportPortalClient;
import com.epam.reportportal.testng.integration.feature.description.DescriptionFailedTest;
import com.epam.reportportal.utils.MemoizingSupplier;
import com.epam.reportportal.utils.markdown.MarkdownUtils;
import com.epam.ta.reportportal.ws.model.FinishTestItemRQ;
import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ;
import java.util.Calendar;
Expand Down Expand Up @@ -67,11 +68,10 @@ private static Launch getLaunch(ListenerParameters parameters) {
private final String testClassUuid = namedUuid("class");
private final String assertionError = "java.lang.AssertionError: " + ASSERT_ERROR;
private final String noSuchElementException = "java.util.NoSuchElementException: " + NO_SUCH_ELEMENT_EXCEPTION;
private final String empty = "";
private final String testDescriptionTestAssertErrorMessage = String.format(DESCRIPTION_ERROR_FORMAT, TEST_DESCRIPTION, assertionError);
private final String testDescriptionTestExceptionMessage = String.format(DESCRIPTION_ERROR_FORMAT, TEST_DESCRIPTION, noSuchElementException);
private final String testWithoutDescriptionTestAssertErrorMessage = String.format(DESCRIPTION_ERROR_FORMAT, empty, assertionError).trim();
private final String testWithoutDescriptionTestExceptionMessage = String.format(DESCRIPTION_ERROR_FORMAT, empty, noSuchElementException).trim();
private final String testDescriptionTestAssertErrorMessage = MarkdownUtils.asTwoParts(TEST_DESCRIPTION, String.format(DESCRIPTION_ERROR_FORMAT, assertionError));
private final String testDescriptionTestExceptionMessage = MarkdownUtils.asTwoParts(TEST_DESCRIPTION, String.format(DESCRIPTION_ERROR_FORMAT, noSuchElementException));
private final String testWithoutDescriptionTestAssertErrorMessage = String.format(DESCRIPTION_ERROR_FORMAT, assertionError).trim();
private final String testWithoutDescriptionTestExceptionMessage = String.format(DESCRIPTION_ERROR_FORMAT, noSuchElementException).trim();

@Mock
private ReportPortalClient client;
Expand Down