Skip to content

Commit

Permalink
Version 2023.03.28: Cucumber runner reworked, fixed RuntimeException …
Browse files Browse the repository at this point in the history
…at setup/teardown
  • Loading branch information
KMariusz committed Mar 28, 2023
1 parent 4935b65 commit 8080f56
Show file tree
Hide file tree
Showing 14 changed files with 242 additions and 48 deletions.
6 changes: 3 additions & 3 deletions mrchecker-framework-modules/mrchecker-cli-module/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
<parent>
<artifactId>mrchecker-test-framework</artifactId>
<groupId>com.capgemini.mrchecker</groupId>
<version>2023.03.20</version>
<version>2023.03.28</version>
</parent>

<artifactId>mrchecker-cli-module</artifactId>
<version>2023.03.20</version>
<version>2023.03.28</version>
<packaging>jar</packaging>
<name>MrChecker - CLI - Module</name>
<description>MrChecker CLI Module supports:
Expand Down Expand Up @@ -60,7 +60,7 @@
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mrchecker-core-module</artifactId>
<version>2023.03.20</version>
<version>2023.03.28</version>
</dependency>
</dependencies>

Expand Down
4 changes: 2 additions & 2 deletions mrchecker-framework-modules/mrchecker-core-module/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
<parent>
<artifactId>mrchecker-test-framework</artifactId>
<groupId>com.capgemini.mrchecker</groupId>
<version>2023.03.20</version>
<version>2023.03.28</version>
</parent>

<artifactId>mrchecker-core-module</artifactId>
<version>2023.03.20</version>
<version>2023.03.28</version>
<packaging>jar</packaging>
<name>MrChecker - Test core - Module</name>
<description>MrChecker Test Framework Core is responsible for:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,7 @@ public void beforeTestExecution(ExtensionContext context) {
try {
validateTestClassAndCallHook(context, BaseTest::setUp);
} catch (Throwable throwable) {
try {
handleExecutionException(context, throwable, "setup", ITestObserver::onSetupFailure);
} catch (Throwable e) {
throw new RuntimeException(e);
}
handleExecutionExceptionAction(context, throwable, "setup", ITestObserver::onSetupFailure);
throw throwable;
}
}
Expand All @@ -99,11 +95,7 @@ public void afterTestExecution(ExtensionContext context) {
try {
validateTestClassAndCallHook(context, BaseTest::tearDown);
} catch (Throwable throwable) {
try {
handleExecutionException(context, throwable, "teardown", ITestObserver::onTeardownFailure);
} catch (Throwable e) {
throw new RuntimeException(e);
}
handleExecutionExceptionAction(context, throwable, "teardown", ITestObserver::onTeardownFailure);
throw throwable;
}
}
Expand All @@ -125,11 +117,15 @@ synchronized public void afterAll(ExtensionContext extensionContext) {
}

//LifecycleMethodExecutionExceptionHandler
private void handleExecutionException(ExtensionContext context, Throwable throwable, String annotationName, Consumer<ITestObserver> action) throws Throwable {
private void handleExecutionExceptionAction(ExtensionContext context, Throwable throwable, String annotationName, Consumer<ITestObserver> action) {
forEachObserver(action);
String className = context.getRequiredTestClass().getName();
String testName = context.getDisplayName();
BFLogger.logError("\"" + className + "#" + testName + "\"" + " - EXCEPTION in " + annotationName + ": " + throwable.getMessage());
}

private void handleExecutionException(ExtensionContext context, Throwable throwable, String annotationName, Consumer<ITestObserver> action) throws Throwable {
handleExecutionExceptionAction(context, throwable, annotationName, action);
throw throwable;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package com.capgemini.mrchecker.test.core.cucumber;

import com.capgemini.mrchecker.test.core.BaseTest;
import com.capgemini.mrchecker.test.core.TestExecutionObserver;
import io.cucumber.java.Scenario;
import io.qameta.allure.Allure;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExecutableInvoker;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.TestInstances;
import org.junit.jupiter.api.parallel.ExecutionMode;

import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;

public abstract class BaseHook {
private final CucumberExtensionContext context;

public BaseHook(BaseTest baseTest) {
// Initializes environment
// Include any global actions before Scenario
// If no global action needed. Please create separate Hook class with Cucumber Before
// Include any global actions after Scenario.
// If no global action needed. Please create separate Hook class with Cucumber After
context = new CucumberExtensionContext(baseTest);
}

public BaseHook() {
this(new BaseTest() {
});
}

public void setup(Scenario scenario) {
context.setDisplayName(scenario.getName());
Allure.suite(getFeatureFileNameFromId(scenario.getId()));
TestExecutionObserver.getInstance().beforeTestExecution(context);
}

private String getFeatureFileNameFromId(String id) {
int slashIndex = id.lastIndexOf("/");
if (slashIndex > -1) {
id = id.substring(slashIndex + 1);
}
int dotIndex = id.indexOf(".");
if (dotIndex > -1) {
id = id.substring(0, dotIndex);
}
return id;
}

public void tearDown(Scenario scenario) {
switch (scenario.getStatus()) {
case SKIPPED:
TestExecutionObserver.getInstance().testAborted(context, null);
break;
case PASSED:
TestExecutionObserver.getInstance().testSuccessful(context);
break;
case FAILED:
TestExecutionObserver.getInstance().testFailed(context, null);
break;
case UNUSED:
case PENDING:
case AMBIGUOUS:
case UNDEFINED:
default:
TestExecutionObserver.getInstance().testDisabled(context, null);
break;
}
TestExecutionObserver.getInstance().afterTestExecution(context);
}

public static class CucumberExtensionContext implements ExtensionContext {
private String testName;
private final BaseTest testInstance;

private CucumberExtensionContext(BaseTest testInstance) {
this.testInstance = testInstance;
}

@Override
public Optional<ExtensionContext> getParent() {
return Optional.empty();
}

@Override
public ExtensionContext getRoot() {
return null;
}

@Override
public String getUniqueId() {
return null;
}

@Override
public String getDisplayName() {
return testName;
}

public void setDisplayName(String testName) {
this.testName = testName;
}

@Override
public Set<String> getTags() {
return null;
}

@Override
public Optional<AnnotatedElement> getElement() {
return Optional.empty();
}

@Override
public Optional<Class<?>> getTestClass() {
return Optional.of(testInstance.getClass());
}

@Override
public Optional<TestInstance.Lifecycle> getTestInstanceLifecycle() {
return Optional.empty();
}

@Override
public Optional<Object> getTestInstance() {
return Optional.of(testInstance);
}

@Override
public Optional<TestInstances> getTestInstances() {
return Optional.empty();
}

@Override
public Optional<Method> getTestMethod() {
return Optional.empty();
}

@Override
public Optional<Throwable> getExecutionException() {
return Optional.empty();
}

@Override
public Optional<String> getConfigurationParameter(String s) {
return Optional.empty();
}

@Override
public void publishReportEntry(Map<String, String> map) {
}

@Override
public Store getStore(Namespace namespace) {
return null;
}

@Override
public ExecutionMode getExecutionMode() {
return null;
}

@Override
public ExecutableInvoker getExecutableInvoker() {
return null;
}

@Override
public <T> Optional<T> getConfigurationParameter(String key, Function<String, T> transformer) {
// TODO Auto-generated method stub
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.capgemini.mrchecker.test.core.cucumber;


import com.capgemini.mrchecker.test.core.TestExecutionObserver;
import io.cucumber.plugin.ConcurrentEventListener;
import io.cucumber.plugin.event.EventHandler;
import io.cucumber.plugin.event.EventPublisher;
import io.cucumber.plugin.event.TestCaseFinished;

public class EventListenerPlugin implements ConcurrentEventListener {
@Override
public void setEventPublisher(EventPublisher eventPublisher) {
eventPublisher.registerHandlerFor(TestCaseFinished.class, teardown);
}

private final EventHandler<TestCaseFinished> teardown = event -> {
TestExecutionObserver.getInstance().afterAll(null);
};
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.capgemini.mrchecker.test.core.logger;

import com.capgemini.mrchecker.test.core.cucumber.BaseHook;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.extension.ExtensionContext;

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

@Override
public ITestName parseFromContext(ExtensionContext context) {
return context.getRequiredTestClass()
.getName()
.contains("BaseHook") ? parseCucumber(context) : parseJUnit(context);
return context instanceof BaseHook.CucumberExtensionContext ? parseCucumber(context) : parseJUnit(context);
}

private static ITestName parseCucumber(ExtensionContext context) {
Expand Down Expand Up @@ -51,4 +50,4 @@ private static ITestName parseJUnit(ExtensionContext context) {

return JunitRunnerTestName.parseString(sb.toString());
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.capgemini.mrchecker.test.core.integration.logger;

import com.capgemini.mrchecker.test.core.cucumber.BaseHook;
import com.capgemini.mrchecker.test.core.logger.ITestName;
import com.capgemini.mrchecker.test.core.logger.ITestNameParser;
import com.capgemini.mrchecker.test.core.logger.JunitOrCucumberRunnerTestNameParser;
Expand Down Expand Up @@ -33,7 +34,7 @@ public class JunitAndCucumberRunnerTestNameParserTest {
@Test
public void shouldParseJunitRunnerNoDDTName() throws NoSuchMethodException {
ITestName parsedTestName = SUT.parseFromContext(
createMockedExtensionContext(JUNIT_RUNNER_DISPLAYED_NAME_NO_DDT, JUNIT_RUNNER_UNIQUE_ID_NO_DDT, Object.class, getClass().getMethod("shouldParseJunitRunnerNoDDTName")));
createMockedExtensionContext(JUNIT_RUNNER_DISPLAYED_NAME_NO_DDT, JUNIT_RUNNER_UNIQUE_ID_NO_DDT, Object.class, getClass().getMethod("shouldParseJunitRunnerNoDDTName"), ExtensionContext.class));

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

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

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

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

assertThat(parsedTestName.getJunitName(), is(equalTo(CUCUMBER_RUNNER_DISPLAYED_NAME)));
assertThat(parsedTestName.getAllureName(), is(equalTo(CUCUMBER_RUNNER_DISPLAYED_NAME)));
}

private static ExtensionContext createMockedExtensionContext(String displayedTestName, String uniqueId, Class testInstanceClass, Method testMethod) {
ExtensionContext contextMock = mock(ExtensionContext.class);
private static ExtensionContext createMockedExtensionContext(String displayedTestName, String uniqueId, Class testInstanceClass, Method testMethod, Class extensionContextClass) {
ExtensionContext contextMock = (ExtensionContext) mock(extensionContextClass);
when(contextMock.getDisplayName()).thenReturn(displayedTestName);
when(contextMock.getUniqueId()).thenReturn(uniqueId);
when(contextMock.getRequiredTestClass()).thenReturn(testInstanceClass);
Expand All @@ -90,4 +91,4 @@ private static ExtensionContext createMockedExtensionContext(String displayedTes

private static class BaseHookTest {
}
}
}
6 changes: 3 additions & 3 deletions mrchecker-framework-modules/mrchecker-database-module/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
<parent>
<artifactId>mrchecker-test-framework</artifactId>
<groupId>com.capgemini.mrchecker</groupId>
<version>2023.03.20</version>
<version>2023.03.28</version>
</parent>

<artifactId>mrchecker-database-module</artifactId>
<version>2023.03.20</version>
<version>2023.03.28</version>
<packaging>jar</packaging>
<name>MrChecker - Database - Module</name>
<description>MrChecker Database Module:
Expand Down Expand Up @@ -80,7 +80,7 @@
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mrchecker-core-module</artifactId>
<version>2023.03.20</version>
<version>2023.03.28</version>
</dependency>

<!-- JPA dependencies -->
Expand Down
Loading

0 comments on commit 8080f56

Please sign in to comment.