Skip to content

Commit 2f0b143

Browse files
authored
fix assertj soft assertions and binary data processing (fixes #347, via #389)
1 parent d5d5c90 commit 2f0b143

File tree

8 files changed

+105
-35
lines changed

8 files changed

+105
-35
lines changed

allure-assertj/src/main/java/io/qameta/allure/assertj/AllureAspectJ.java

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,24 @@
1919
import io.qameta.allure.AllureLifecycle;
2020
import io.qameta.allure.model.Status;
2121
import io.qameta.allure.model.StepResult;
22-
import org.aspectj.lang.ProceedingJoinPoint;
23-
import org.aspectj.lang.annotation.Around;
22+
import io.qameta.allure.util.ObjectUtils;
23+
import org.aspectj.lang.JoinPoint;
24+
import org.aspectj.lang.annotation.After;
25+
import org.aspectj.lang.annotation.AfterReturning;
26+
import org.aspectj.lang.annotation.AfterThrowing;
2427
import org.aspectj.lang.annotation.Aspect;
28+
import org.aspectj.lang.annotation.Before;
29+
import org.aspectj.lang.annotation.Pointcut;
2530
import org.aspectj.lang.reflect.MethodSignature;
2631
import org.slf4j.Logger;
2732
import org.slf4j.LoggerFactory;
2833

29-
import java.util.Objects;
3034
import java.util.UUID;
3135
import java.util.stream.Collectors;
3236
import java.util.stream.Stream;
3337

3438
import static io.qameta.allure.util.ResultsUtils.getStatus;
3539
import static io.qameta.allure.util.ResultsUtils.getStatusDetails;
36-
import static java.util.Objects.nonNull;
3740

3841
/**
3942
* @author charlie (Dmitry Baev).
@@ -52,29 +55,64 @@ protected AllureLifecycle initialValue() {
5255
}
5356
};
5457

55-
@Around("execution(* org.assertj.core.api.AbstractAssert+.*(..)) "
56-
+ "|| execution(* org.assertj.core.api.Assertions.assertThat(..))")
57-
public Object step(final ProceedingJoinPoint joinPoint) throws Throwable {
58+
@Pointcut("execution(public org.assertj.core.api.AbstractAssert.new(..))")
59+
public void anyAssertCreation() {
60+
//pointcut body, should be empty
61+
}
62+
63+
@Pointcut("execution(* org.assertj.core.api.AssertJProxySetup.*(..))")
64+
public void proxyMethod() {
65+
//pointcut body, should be empty
66+
}
67+
68+
@Pointcut("execution(public * org.assertj.core.api.AbstractAssert+.*(..)) && !proxyMethod()")
69+
public void anyAssert() {
70+
//pointcut body, should be empty
71+
}
72+
73+
@After("anyAssertCreation()")
74+
public void logAssertCreation(final JoinPoint joinPoint) {
75+
final String actual = joinPoint.getArgs().length > 0
76+
? ObjectUtils.toString(joinPoint.getArgs()[0])
77+
: "<?>";
78+
final String uuid = UUID.randomUUID().toString();
79+
final String name = String.format("assertThat \'%s\'", actual);
80+
81+
final StepResult result = new StepResult()
82+
.setName(name)
83+
.setStatus(Status.PASSED);
84+
85+
getLifecycle().startStep(uuid, result);
86+
getLifecycle().stopStep(uuid);
87+
}
88+
89+
@Before("anyAssert()")
90+
public void stepStart(final JoinPoint joinPoint) {
5891
final MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
92+
93+
final String uuid = UUID.randomUUID().toString();
5994
final String name = joinPoint.getArgs().length > 0
6095
? String.format("%s \'%s\'", methodSignature.getName(), arrayToString(joinPoint.getArgs()))
6196
: methodSignature.getName();
62-
final String uuid = UUID.randomUUID().toString();
97+
6398
final StepResult result = new StepResult()
6499
.setName(name);
100+
65101
getLifecycle().startStep(uuid, result);
66-
try {
67-
final Object proceed = joinPoint.proceed();
68-
getLifecycle().updateStep(uuid, s -> s.setStatus(Status.PASSED));
69-
return proceed;
70-
} catch (Throwable e) {
71-
getLifecycle().updateStep(uuid, s -> s
72-
.setStatus(getStatus(e).orElse(Status.BROKEN))
73-
.setStatusDetails(getStatusDetails(e).orElse(null)));
74-
throw e;
75-
} finally {
76-
getLifecycle().stopStep(uuid);
77-
}
102+
}
103+
104+
@AfterThrowing(pointcut = "anyAssert()", throwing = "e")
105+
public void stepFailed(final Throwable e) {
106+
getLifecycle().updateStep(s -> s
107+
.setStatus(getStatus(e).orElse(Status.BROKEN))
108+
.setStatusDetails(getStatusDetails(e).orElse(null)));
109+
getLifecycle().stopStep();
110+
}
111+
112+
@AfterReturning(pointcut = "anyAssert()")
113+
public void stepStop() {
114+
getLifecycle().updateStep(s -> s.setStatus(Status.PASSED));
115+
getLifecycle().stopStep();
78116
}
79117

80118
/**
@@ -92,9 +130,7 @@ public static AllureLifecycle getLifecycle() {
92130

93131
private static String arrayToString(final Object... array) {
94132
return Stream.of(array)
95-
.map(object -> nonNull(object) && object.getClass().isArray()
96-
? arrayToString((Object[]) object)
97-
: Objects.toString(object))
133+
.map(ObjectUtils::toString)
98134
.collect(Collectors.joining(" "));
99135
}
100136
}

allure-assertj/src/test/java/io/qameta/allure/assertj/AllureAspectJTest.java

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import org.assertj.core.api.SoftAssertions;
2323
import org.junit.jupiter.api.Test;
2424

25+
import java.nio.charset.StandardCharsets;
26+
2527
import static io.qameta.allure.test.RunUtils.runWithinTestContext;
2628
import static org.assertj.core.api.Assertions.assertThat;
2729

@@ -40,33 +42,65 @@ void shouldCreateStepsForAsserts() {
4042
assertThat(results.getTestResults())
4143
.flatExtracting(TestResult::getSteps)
4244
.extracting(StepResult::getName)
43-
.containsExactly("assertThat 'Data'", "hasSize '4'");
45+
.containsExactly(
46+
"assertThat 'Data'",
47+
"hasSize '4'"
48+
);
4449
}
4550

4651
@AllureFeatures.Steps
4752
@Test
4853
void shouldHandleNullableObject() {
4954
final AllureResults results = runWithinTestContext(() -> {
50-
assertThat((Object) null).as("Nullable object").isNull();
55+
assertThat((Object) null)
56+
.as("Nullable object")
57+
.isNull();
58+
}, AllureAspectJ::setLifecycle);
59+
60+
assertThat(results.getTestResults())
61+
.flatExtracting(TestResult::getSteps)
62+
.extracting(StepResult::getName)
63+
.containsExactly(
64+
"assertThat 'null'",
65+
"as 'Nullable object []'",
66+
"isNull"
67+
);
68+
}
69+
70+
@AllureFeatures.Steps
71+
@Test
72+
void shouldHandleByteArrayObject() {
73+
final String s = "some string";
74+
final AllureResults results = runWithinTestContext(() -> {
75+
assertThat(s.getBytes(StandardCharsets.UTF_8))
76+
.as("Byte array object")
77+
.isEqualTo(s.getBytes(StandardCharsets.UTF_8));
5178
}, AllureAspectJ::setLifecycle);
5279

5380
assertThat(results.getTestResults())
5481
.flatExtracting(TestResult::getSteps)
5582
.extracting(StepResult::getName)
56-
.containsExactly("assertThat 'null'", "as 'Nullable object '", "isNull");
83+
.containsExactly(
84+
"assertThat '<BINARY>'",
85+
"as 'Byte array object []'",
86+
"isEqualTo '<BINARY>'"
87+
);
5788
}
5889

5990
@AllureFeatures.Steps
6091
@Test
6192
void softAssertions() {
6293
final AllureResults results = runWithinTestContext(() -> {
6394
final SoftAssertions soft = new SoftAssertions();
64-
soft.assertThat(25).as("Test description").isEqualTo(26);
95+
soft.assertThat(25)
96+
.as("Test description")
97+
.isEqualTo(26);
98+
soft.assertAll();
6599
}, AllureAspectJ::setLifecycle);
66100

67101
assertThat(results.getTestResults())
68102
.flatExtracting(TestResult::getSteps)
69103
.extracting(StepResult::getName)
70-
.contains("as 'Test description '", "isEqualTo '26'");
104+
.contains("as 'Test description []'", "isEqualTo '26'");
71105
}
72106
}

allure-java-commons/src/main/java/io/qameta/allure/util/ObjectUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public static String toString(final Object object) {
6767
} else if (object instanceof boolean[]) {
6868
return Arrays.toString((boolean[]) object);
6969
} else if (object instanceof byte[]) {
70-
return Arrays.toString((byte[]) object);
70+
return "<BINARY>";
7171
}
7272
}
7373
return Objects.toString(object);

build.gradle.kts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ val qualityConfigsDir by extra("$gradleScriptDir/quality-configs")
3232
val spotlessDtr by extra("$qualityConfigsDir/spotless")
3333

3434
tasks.withType(Wrapper::class) {
35-
gradleVersion = "5.2.1"
35+
gradleVersion = "5.6.1"
3636
}
3737

3838
plugins {
@@ -93,8 +93,8 @@ configure(subprojects) {
9393
dependency("org.apache.commons:commons-lang3:3.8.1")
9494
dependency("org.apache.httpcomponents:httpclient:4.5.7")
9595
dependency("org.apache.tika:tika-core:1.20")
96-
dependency("org.aspectj:aspectjrt:1.9.2")
97-
dependency("org.aspectj:aspectjweaver:1.9.2")
96+
dependency("org.aspectj:aspectjrt:1.9.4")
97+
dependency("org.aspectj:aspectjweaver:1.9.4")
9898
dependency("org.assertj:assertj-core:3.11.1")
9999
dependency("org.codehaus.groovy:groovy-all:2.5.6")
100100
dependency("org.freemarker:freemarker:2.3.28")

gradle/wrapper/gradle-wrapper.jar

-987 Bytes
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.1-bin.zip
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists

gradlew

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gradlew.bat

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)