Skip to content

Commit 8080f56

Browse files
committed
Version 2023.03.28: Cucumber runner reworked, fixed RuntimeException at setup/teardown
1 parent 4935b65 commit 8080f56

File tree

14 files changed

+242
-48
lines changed

14 files changed

+242
-48
lines changed

mrchecker-framework-modules/mrchecker-cli-module/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
<parent>
77
<artifactId>mrchecker-test-framework</artifactId>
88
<groupId>com.capgemini.mrchecker</groupId>
9-
<version>2023.03.20</version>
9+
<version>2023.03.28</version>
1010
</parent>
1111

1212
<artifactId>mrchecker-cli-module</artifactId>
13-
<version>2023.03.20</version>
13+
<version>2023.03.28</version>
1414
<packaging>jar</packaging>
1515
<name>MrChecker - CLI - Module</name>
1616
<description>MrChecker CLI Module supports:
@@ -60,7 +60,7 @@
6060
<dependency>
6161
<groupId>${project.groupId}</groupId>
6262
<artifactId>mrchecker-core-module</artifactId>
63-
<version>2023.03.20</version>
63+
<version>2023.03.28</version>
6464
</dependency>
6565
</dependencies>
6666

mrchecker-framework-modules/mrchecker-core-module/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
<parent>
88
<artifactId>mrchecker-test-framework</artifactId>
99
<groupId>com.capgemini.mrchecker</groupId>
10-
<version>2023.03.20</version>
10+
<version>2023.03.28</version>
1111
</parent>
1212

1313
<artifactId>mrchecker-core-module</artifactId>
14-
<version>2023.03.20</version>
14+
<version>2023.03.28</version>
1515
<packaging>jar</packaging>
1616
<name>MrChecker - Test core - Module</name>
1717
<description>MrChecker Test Framework Core is responsible for:

mrchecker-framework-modules/mrchecker-core-module/src/main/java/com/capgemini/mrchecker/test/core/TestExecutionObserver.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,7 @@ public void beforeTestExecution(ExtensionContext context) {
8181
try {
8282
validateTestClassAndCallHook(context, BaseTest::setUp);
8383
} catch (Throwable throwable) {
84-
try {
85-
handleExecutionException(context, throwable, "setup", ITestObserver::onSetupFailure);
86-
} catch (Throwable e) {
87-
throw new RuntimeException(e);
88-
}
84+
handleExecutionExceptionAction(context, throwable, "setup", ITestObserver::onSetupFailure);
8985
throw throwable;
9086
}
9187
}
@@ -99,11 +95,7 @@ public void afterTestExecution(ExtensionContext context) {
9995
try {
10096
validateTestClassAndCallHook(context, BaseTest::tearDown);
10197
} catch (Throwable throwable) {
102-
try {
103-
handleExecutionException(context, throwable, "teardown", ITestObserver::onTeardownFailure);
104-
} catch (Throwable e) {
105-
throw new RuntimeException(e);
106-
}
98+
handleExecutionExceptionAction(context, throwable, "teardown", ITestObserver::onTeardownFailure);
10799
throw throwable;
108100
}
109101
}
@@ -125,11 +117,15 @@ synchronized public void afterAll(ExtensionContext extensionContext) {
125117
}
126118

127119
//LifecycleMethodExecutionExceptionHandler
128-
private void handleExecutionException(ExtensionContext context, Throwable throwable, String annotationName, Consumer<ITestObserver> action) throws Throwable {
120+
private void handleExecutionExceptionAction(ExtensionContext context, Throwable throwable, String annotationName, Consumer<ITestObserver> action) {
129121
forEachObserver(action);
130122
String className = context.getRequiredTestClass().getName();
131123
String testName = context.getDisplayName();
132124
BFLogger.logError("\"" + className + "#" + testName + "\"" + " - EXCEPTION in " + annotationName + ": " + throwable.getMessage());
125+
}
126+
127+
private void handleExecutionException(ExtensionContext context, Throwable throwable, String annotationName, Consumer<ITestObserver> action) throws Throwable {
128+
handleExecutionExceptionAction(context, throwable, annotationName, action);
133129
throw throwable;
134130
}
135131

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
package com.capgemini.mrchecker.test.core.cucumber;
2+
3+
import com.capgemini.mrchecker.test.core.BaseTest;
4+
import com.capgemini.mrchecker.test.core.TestExecutionObserver;
5+
import io.cucumber.java.Scenario;
6+
import io.qameta.allure.Allure;
7+
import org.junit.jupiter.api.TestInstance;
8+
import org.junit.jupiter.api.extension.ExecutableInvoker;
9+
import org.junit.jupiter.api.extension.ExtensionContext;
10+
import org.junit.jupiter.api.extension.TestInstances;
11+
import org.junit.jupiter.api.parallel.ExecutionMode;
12+
13+
import java.lang.reflect.AnnotatedElement;
14+
import java.lang.reflect.Method;
15+
import java.util.Map;
16+
import java.util.Optional;
17+
import java.util.Set;
18+
import java.util.function.Function;
19+
20+
public abstract class BaseHook {
21+
private final CucumberExtensionContext context;
22+
23+
public BaseHook(BaseTest baseTest) {
24+
// Initializes environment
25+
// Include any global actions before Scenario
26+
// If no global action needed. Please create separate Hook class with Cucumber Before
27+
// Include any global actions after Scenario.
28+
// If no global action needed. Please create separate Hook class with Cucumber After
29+
context = new CucumberExtensionContext(baseTest);
30+
}
31+
32+
public BaseHook() {
33+
this(new BaseTest() {
34+
});
35+
}
36+
37+
public void setup(Scenario scenario) {
38+
context.setDisplayName(scenario.getName());
39+
Allure.suite(getFeatureFileNameFromId(scenario.getId()));
40+
TestExecutionObserver.getInstance().beforeTestExecution(context);
41+
}
42+
43+
private String getFeatureFileNameFromId(String id) {
44+
int slashIndex = id.lastIndexOf("/");
45+
if (slashIndex > -1) {
46+
id = id.substring(slashIndex + 1);
47+
}
48+
int dotIndex = id.indexOf(".");
49+
if (dotIndex > -1) {
50+
id = id.substring(0, dotIndex);
51+
}
52+
return id;
53+
}
54+
55+
public void tearDown(Scenario scenario) {
56+
switch (scenario.getStatus()) {
57+
case SKIPPED:
58+
TestExecutionObserver.getInstance().testAborted(context, null);
59+
break;
60+
case PASSED:
61+
TestExecutionObserver.getInstance().testSuccessful(context);
62+
break;
63+
case FAILED:
64+
TestExecutionObserver.getInstance().testFailed(context, null);
65+
break;
66+
case UNUSED:
67+
case PENDING:
68+
case AMBIGUOUS:
69+
case UNDEFINED:
70+
default:
71+
TestExecutionObserver.getInstance().testDisabled(context, null);
72+
break;
73+
}
74+
TestExecutionObserver.getInstance().afterTestExecution(context);
75+
}
76+
77+
public static class CucumberExtensionContext implements ExtensionContext {
78+
private String testName;
79+
private final BaseTest testInstance;
80+
81+
private CucumberExtensionContext(BaseTest testInstance) {
82+
this.testInstance = testInstance;
83+
}
84+
85+
@Override
86+
public Optional<ExtensionContext> getParent() {
87+
return Optional.empty();
88+
}
89+
90+
@Override
91+
public ExtensionContext getRoot() {
92+
return null;
93+
}
94+
95+
@Override
96+
public String getUniqueId() {
97+
return null;
98+
}
99+
100+
@Override
101+
public String getDisplayName() {
102+
return testName;
103+
}
104+
105+
public void setDisplayName(String testName) {
106+
this.testName = testName;
107+
}
108+
109+
@Override
110+
public Set<String> getTags() {
111+
return null;
112+
}
113+
114+
@Override
115+
public Optional<AnnotatedElement> getElement() {
116+
return Optional.empty();
117+
}
118+
119+
@Override
120+
public Optional<Class<?>> getTestClass() {
121+
return Optional.of(testInstance.getClass());
122+
}
123+
124+
@Override
125+
public Optional<TestInstance.Lifecycle> getTestInstanceLifecycle() {
126+
return Optional.empty();
127+
}
128+
129+
@Override
130+
public Optional<Object> getTestInstance() {
131+
return Optional.of(testInstance);
132+
}
133+
134+
@Override
135+
public Optional<TestInstances> getTestInstances() {
136+
return Optional.empty();
137+
}
138+
139+
@Override
140+
public Optional<Method> getTestMethod() {
141+
return Optional.empty();
142+
}
143+
144+
@Override
145+
public Optional<Throwable> getExecutionException() {
146+
return Optional.empty();
147+
}
148+
149+
@Override
150+
public Optional<String> getConfigurationParameter(String s) {
151+
return Optional.empty();
152+
}
153+
154+
@Override
155+
public void publishReportEntry(Map<String, String> map) {
156+
}
157+
158+
@Override
159+
public Store getStore(Namespace namespace) {
160+
return null;
161+
}
162+
163+
@Override
164+
public ExecutionMode getExecutionMode() {
165+
return null;
166+
}
167+
168+
@Override
169+
public ExecutableInvoker getExecutableInvoker() {
170+
return null;
171+
}
172+
173+
@Override
174+
public <T> Optional<T> getConfigurationParameter(String key, Function<String, T> transformer) {
175+
// TODO Auto-generated method stub
176+
return null;
177+
}
178+
}
179+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.capgemini.mrchecker.test.core.cucumber;
2+
3+
4+
import com.capgemini.mrchecker.test.core.TestExecutionObserver;
5+
import io.cucumber.plugin.ConcurrentEventListener;
6+
import io.cucumber.plugin.event.EventHandler;
7+
import io.cucumber.plugin.event.EventPublisher;
8+
import io.cucumber.plugin.event.TestCaseFinished;
9+
10+
public class EventListenerPlugin implements ConcurrentEventListener {
11+
@Override
12+
public void setEventPublisher(EventPublisher eventPublisher) {
13+
eventPublisher.registerHandlerFor(TestCaseFinished.class, teardown);
14+
}
15+
16+
private final EventHandler<TestCaseFinished> teardown = event -> {
17+
TestExecutionObserver.getInstance().afterAll(null);
18+
};
19+
}

mrchecker-framework-modules/mrchecker-core-module/src/main/java/com/capgemini/mrchecker/test/core/logger/JunitOrCucumberRunnerTestNameParser.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.capgemini.mrchecker.test.core.logger;
22

3+
import com.capgemini.mrchecker.test.core.cucumber.BaseHook;
34
import org.junit.jupiter.api.DisplayName;
45
import org.junit.jupiter.api.extension.ExtensionContext;
56

@@ -9,9 +10,7 @@ public class JunitOrCucumberRunnerTestNameParser implements ITestNameParser {
910

1011
@Override
1112
public ITestName parseFromContext(ExtensionContext context) {
12-
return context.getRequiredTestClass()
13-
.getName()
14-
.contains("BaseHook") ? parseCucumber(context) : parseJUnit(context);
13+
return context instanceof BaseHook.CucumberExtensionContext ? parseCucumber(context) : parseJUnit(context);
1514
}
1615

1716
private static ITestName parseCucumber(ExtensionContext context) {
@@ -51,4 +50,4 @@ private static ITestName parseJUnit(ExtensionContext context) {
5150

5251
return JunitRunnerTestName.parseString(sb.toString());
5352
}
54-
}
53+
}

mrchecker-framework-modules/mrchecker-core-module/src/test/java/com/capgemini/mrchecker/test/core/integration/logger/JunitAndCucumberRunnerTestNameParserTest.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.capgemini.mrchecker.test.core.integration.logger;
22

3+
import com.capgemini.mrchecker.test.core.cucumber.BaseHook;
34
import com.capgemini.mrchecker.test.core.logger.ITestName;
45
import com.capgemini.mrchecker.test.core.logger.ITestNameParser;
56
import com.capgemini.mrchecker.test.core.logger.JunitOrCucumberRunnerTestNameParser;
@@ -33,7 +34,7 @@ public class JunitAndCucumberRunnerTestNameParserTest {
3334
@Test
3435
public void shouldParseJunitRunnerNoDDTName() throws NoSuchMethodException {
3536
ITestName parsedTestName = SUT.parseFromContext(
36-
createMockedExtensionContext(JUNIT_RUNNER_DISPLAYED_NAME_NO_DDT, JUNIT_RUNNER_UNIQUE_ID_NO_DDT, Object.class, getClass().getMethod("shouldParseJunitRunnerNoDDTName")));
37+
createMockedExtensionContext(JUNIT_RUNNER_DISPLAYED_NAME_NO_DDT, JUNIT_RUNNER_UNIQUE_ID_NO_DDT, Object.class, getClass().getMethod("shouldParseJunitRunnerNoDDTName"), ExtensionContext.class));
3738

3839
assertThat(parsedTestName.getJunitName(), is(equalTo("com.capgemini.mrchecker.selenium.mts.MyThaiStarTest:Test_orderMenu")));
3940
assertThat(parsedTestName.getAllureName(), is(equalTo("Test_orderMenu")));
@@ -43,7 +44,7 @@ public void shouldParseJunitRunnerNoDDTName() throws NoSuchMethodException {
4344
@DisplayName("shouldParseJunitRunnerNoDDTAnnotatedName")
4445
public void shouldParseJunitRunnerNoDDTAnnotatedName() throws NoSuchMethodException {
4546
ITestName parsedTestName = SUT.parseFromContext(
46-
createMockedExtensionContext(JUNIT_RUNNER_DISPLAYED_NAME_NO_DDT, JUNIT_RUNNER_UNIQUE_ID_NO_DDT, Object.class, getClass().getMethod("shouldParseJunitRunnerNoDDTAnnotatedName")));
47+
createMockedExtensionContext(JUNIT_RUNNER_DISPLAYED_NAME_NO_DDT, JUNIT_RUNNER_UNIQUE_ID_NO_DDT, Object.class, getClass().getMethod("shouldParseJunitRunnerNoDDTAnnotatedName"), ExtensionContext.class));
4748

4849
assertThat(parsedTestName.getJunitName(), is(equalTo("com.capgemini.mrchecker.selenium.mts.MyThaiStarTest:shouldParseJunitRunnerNoDDTAnnotatedName")));
4950
assertThat(parsedTestName.getAllureName(), is(equalTo("shouldParseJunitRunnerNoDDTAnnotatedName")));
@@ -52,7 +53,7 @@ public void shouldParseJunitRunnerNoDDTAnnotatedName() throws NoSuchMethodExcept
5253
@Test
5354
public void shouldParseJunitRunnerDDTName() throws NoSuchMethodException {
5455
ITestName parsedTestName = SUT
55-
.parseFromContext(createMockedExtensionContext(JUNIT_RUNNER_DISPLAYED_NAME_DDT, JUNIT_RUNNER_UNIQUE_ID_DDT, Object.class, getClass().getMethod("shouldParseJunitRunnerDDTName")));
56+
.parseFromContext(createMockedExtensionContext(JUNIT_RUNNER_DISPLAYED_NAME_DDT, JUNIT_RUNNER_UNIQUE_ID_DDT, Object.class, getClass().getMethod("shouldParseJunitRunnerDDTName"), ExtensionContext.class));
5657

5758
assertThat(parsedTestName.getJunitName(), is(equalTo("com.capgemini.mrchecker.selenium.mts.MyThaiStarTest" + ":" + EXPECTED_ALLURE_NAME_DDT)));
5859
assertThat(parsedTestName.getAllureName(), is(equalTo(EXPECTED_ALLURE_NAME_DDT)));
@@ -63,7 +64,7 @@ public void shouldParseJunitRunnerDDTName() throws NoSuchMethodException {
6364
public void shouldParseJunitRunnerDDTAnnotatedName() throws NoSuchMethodException {
6465
ITestName parsedTestName = SUT
6566
.parseFromContext(
66-
createMockedExtensionContext(JUNIT_RUNNER_DISPLAYED_NAME_DDT, JUNIT_RUNNER_UNIQUE_ID_DDT, Object.class, getClass().getMethod("shouldParseJunitRunnerDDTAnnotatedName")));
67+
createMockedExtensionContext(JUNIT_RUNNER_DISPLAYED_NAME_DDT, JUNIT_RUNNER_UNIQUE_ID_DDT, Object.class, getClass().getMethod("shouldParseJunitRunnerDDTAnnotatedName"), ExtensionContext.class));
6768

6869
assertThat(parsedTestName.getJunitName(), is(equalTo("com.capgemini.mrchecker.selenium.mts.MyThaiStarTest:shouldParseJunitRunnerDDTAnnotatedName: waiter, waiter")));
6970
assertThat(parsedTestName.getAllureName(), is(equalTo("shouldParseJunitRunnerDDTAnnotatedName: waiter, waiter")));
@@ -73,14 +74,14 @@ public void shouldParseJunitRunnerDDTAnnotatedName() throws NoSuchMethodExceptio
7374
public void shouldParseCucumberRunnerName() throws NoSuchMethodException {
7475
ITestName parsedTestName = SUT
7576
.parseFromContext(
76-
createMockedExtensionContext(CUCUMBER_RUNNER_DISPLAYED_NAME, CUCUMBER_RUNNER_UNIQUE_ID_DDT, BaseHookTest.class, getClass().getMethod("shouldParseCucumberRunnerName")));
77+
createMockedExtensionContext(CUCUMBER_RUNNER_DISPLAYED_NAME, CUCUMBER_RUNNER_UNIQUE_ID_DDT, BaseHookTest.class, getClass().getMethod("shouldParseCucumberRunnerName"), BaseHook.CucumberExtensionContext.class));
7778

7879
assertThat(parsedTestName.getJunitName(), is(equalTo(CUCUMBER_RUNNER_DISPLAYED_NAME)));
7980
assertThat(parsedTestName.getAllureName(), is(equalTo(CUCUMBER_RUNNER_DISPLAYED_NAME)));
8081
}
8182

82-
private static ExtensionContext createMockedExtensionContext(String displayedTestName, String uniqueId, Class testInstanceClass, Method testMethod) {
83-
ExtensionContext contextMock = mock(ExtensionContext.class);
83+
private static ExtensionContext createMockedExtensionContext(String displayedTestName, String uniqueId, Class testInstanceClass, Method testMethod, Class extensionContextClass) {
84+
ExtensionContext contextMock = (ExtensionContext) mock(extensionContextClass);
8485
when(contextMock.getDisplayName()).thenReturn(displayedTestName);
8586
when(contextMock.getUniqueId()).thenReturn(uniqueId);
8687
when(contextMock.getRequiredTestClass()).thenReturn(testInstanceClass);
@@ -90,4 +91,4 @@ private static ExtensionContext createMockedExtensionContext(String displayedTes
9091

9192
private static class BaseHookTest {
9293
}
93-
}
94+
}

mrchecker-framework-modules/mrchecker-database-module/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
<parent>
77
<artifactId>mrchecker-test-framework</artifactId>
88
<groupId>com.capgemini.mrchecker</groupId>
9-
<version>2023.03.20</version>
9+
<version>2023.03.28</version>
1010
</parent>
1111

1212
<artifactId>mrchecker-database-module</artifactId>
13-
<version>2023.03.20</version>
13+
<version>2023.03.28</version>
1414
<packaging>jar</packaging>
1515
<name>MrChecker - Database - Module</name>
1616
<description>MrChecker Database Module:
@@ -80,7 +80,7 @@
8080
<dependency>
8181
<groupId>${project.groupId}</groupId>
8282
<artifactId>mrchecker-core-module</artifactId>
83-
<version>2023.03.20</version>
83+
<version>2023.03.28</version>
8484
</dependency>
8585

8686
<!-- JPA dependencies -->

0 commit comments

Comments
 (0)