Skip to content

Commit

Permalink
feat(#1218): add events onTestEnd, onFinalActionsEnd, onAfterSequence…
Browse files Browse the repository at this point in the history
…BeforeTest and onAfterSequenceAfterTest
  • Loading branch information
phos-web committed Feb 6, 2025
1 parent cb889b2 commit 32f2a48
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,69 @@
*/
public interface TestListener {
/**
* Invoked when test gets started
* @param test
* Invoked when test when a test starts execution
*/
void onTestStart(TestCase test);

/**
* Invoked when test gets finished
* @param test
* Invoked when all test action executions have finished but before final actions execution and AfterSequence execution
*/
void onTestFinish(TestCase test);

/**
* Invoked when test finished with success
* @param test
* Invoked when a test finishes successfully
*/
void onTestSuccess(TestCase test);

/**
* Invoked when test finished with failure
* @param test
* Invoked when a test finishes with failure
*/
void onTestFailure(TestCase test, Throwable cause);

/**
* Invoked when test is skipped
* @param test
* Invoked when a test is skipped
*/
void onTestSkipped(TestCase test);

/**
* Invoked when test execution has completely ended (including final actions and sequences)
*/
default void onTestEnd(TestCase test) {
// Default implementation does nothing
}

/**
* Invoked after final actions have completely finished
*/
default void onFinalActionsEnd(TestCase test) {
// Default implementation does nothing
}

/**
* Invoked after the AfterSequence but before the test has fully ended
*/
default void onAfterSequenceBeforeTest(TestCase test) {
// Default implementation does nothing
}

/**
* Invoked after the AfterSequence and after the test execution
*/
default void onAfterSequenceAfterTest(TestCase test) {
// Default implementation does nothing
}

/**
* Invoked before the sequence and before the test execution
*/
default void onBeforeSequenceBeforeTest(TestCase test) {
// Default implementation does nothing
}

/**
* Invoked before the sequence but after the test execution
*/
default void onBeforeSequenceAfterTest(TestCase test) {
// Default implementation does nothing
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,42 @@ public void onTestStart(TestCase test) {
}
}

public void onTestEnd(TestCase test) {
for (TestListener listener : testListeners) {
listener.onTestEnd(test);
}
}

public void onFinalActionsEnd(TestCase test) {
for (TestListener listener : testListeners) {
listener.onFinalActionsEnd(test);
}
}

public void onAfterSequenceBeforeTest(TestCase test) {
for (TestListener listener : testListeners) {
listener.onAfterSequenceBeforeTest(test);
}
}

public void onAfterSequenceAfterTest(TestCase test) {
for (TestListener listener : testListeners) {
listener.onAfterSequenceAfterTest(test);
}
}

public void onBeforeSequenceBeforeTest(TestCase test) {
for (TestListener listener : testListeners) {
listener.onBeforeSequenceBeforeTest(test);
}
}

public void onBeforeSequenceAfterTest(TestCase test) {
for (TestListener listener : testListeners) {
listener.onBeforeSequenceAfterTest(test);
}
}

public void onTestSuccess(TestCase test) {
for (TestListener listener : testListeners) {
listener.onTestSuccess(test);
Expand All @@ -70,7 +106,6 @@ public void addTestListener(TestListener listener) {

/**
* Obtains the testListeners.
* @return
*/
public List<TestListener> getTestListeners() {
return testListeners;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ public void beforeTest(final TestContext context) {
throw new CitrusRuntimeException("Before test failed with errors", e);
}
}
context.getTestListeners().onAfterSequenceBeforeTest(this);
}

@Override
Expand All @@ -179,6 +180,7 @@ public void afterTest(final TestContext context) {
logger.warn("After test failed with errors", e);
}
}
context.getTestListeners().onAfterSequenceAfterTest(this);
}

@Override
Expand Down Expand Up @@ -237,6 +239,7 @@ public void finish(final TestContext context) {

context.getTestListeners().onTestFinish(this);
executeFinalActions(context);
context.getTestListeners().onFinalActionsEnd(this);

if (contextException != null) {
throw new TestCaseFailedException(contextException);
Expand All @@ -261,6 +264,8 @@ public void finish(final TestContext context) {
afterTest(context);

completeTestResultWithDuration();

context.getTestListeners().onTestEnd(this);
}
}

Expand Down Expand Up @@ -326,9 +331,6 @@ private void executeFinalActions(TestContext context) {

/**
* Print variables in given test context.
*
* @param scope
* @param context
*/
private void debugVariables(String scope, TestContext context) {
/* Debug print global variables */
Expand All @@ -342,9 +344,6 @@ private void debugVariables(String scope, TestContext context) {

/**
* Sets test parameters as test variables.
*
* @param parameters
* @param context
*/
private void initializeTestParameters(Map<String, Object> parameters, TestContext context) {
// add default variables for test
Expand All @@ -359,9 +358,6 @@ private void initializeTestParameters(Map<String, Object> parameters, TestContex

/**
* Initialize the test variables in the given test context.
*
* @param variableDefinitions
* @param context
*/
private void initializeTestVariables(Map<String, Object> variableDefinitions, TestContext context) {
/* build up the global test variables in TestContext by
Expand All @@ -381,8 +377,6 @@ private void initializeTestVariables(Map<String, Object> variableDefinitions, Te

/**
* Setter for variables.
*
* @param variableDefinitions
*/
public void setVariableDefinitions(final Map<String, Object> variableDefinitions) {
this.variableDefinitions = variableDefinitions;
Expand All @@ -395,8 +389,6 @@ public Map<String, Object> getVariableDefinitions() {

/**
* Setter for finally chain.
*
* @param finalActions
*/
public void setFinalActions(final List<TestAction> finalActions) {
this.finalActions = finalActions.stream().map(action -> (TestActionBuilder<?>) () -> action).collect(Collectors.toList());
Expand Down Expand Up @@ -543,17 +535,13 @@ public void setGroups(final String[] groups) {

/**
* Sets the timeout.
*
* @param timeout
*/
public void setTimeout(final long timeout) {
this.timeout = timeout;
}

/**
* Gets the timeout.
*
* @return
*/
public long getTimeout() {
return timeout;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.citrusframework;

import org.citrusframework.TestCaseMetaInfo.Status;
import org.citrusframework.actions.AbstractAsyncTestAction;
import org.citrusframework.actions.EchoAction;
import org.citrusframework.actions.SleepAction;
Expand All @@ -10,6 +11,8 @@
import org.citrusframework.exceptions.CitrusRuntimeException;
import org.citrusframework.exceptions.TestCaseFailedException;
import org.citrusframework.functions.core.CurrentDateFunction;
import org.citrusframework.report.TestListener;
import org.mockito.InOrder;
import org.slf4j.LoggerFactory;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
Expand All @@ -26,12 +29,20 @@
import static java.util.Collections.singletonMap;
import static org.citrusframework.DefaultTestActionBuilder.action;
import static org.citrusframework.TestResult.RESULT.FAILURE;
import static org.citrusframework.TestResult.failed;
import static org.citrusframework.TestResult.success;
import static org.citrusframework.util.TestUtils.WAIT_THREAD_PREFIX;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertThrows;
import static org.testng.Assert.fail;

public class DefaultTestCaseTest extends UnitTestSupport {
Expand Down Expand Up @@ -165,6 +176,60 @@ public void doExecuteAsync(final TestContext context) {
}
}

@Test
public void testTestListenerEventsWithSuccessTestResult() {
TestListener testListenerMock = mock();
context.getTestListeners().addTestListener(testListenerMock);

fixture.doExecute(context);
fixture.finish(context);

InOrder inOrder = inOrder(testListenerMock);
inOrder.verify(testListenerMock, times(1)).onTestStart(fixture);
inOrder.verify(testListenerMock, times(1)).onAfterSequenceBeforeTest(fixture);
inOrder.verify(testListenerMock, times(1)).onTestFinish(fixture);
inOrder.verify(testListenerMock, times(1)).onFinalActionsEnd(fixture);
inOrder.verify(testListenerMock, times(1)).onTestSuccess(fixture);
inOrder.verify(testListenerMock, times(1)).onAfterSequenceAfterTest(fixture);
inOrder.verify(testListenerMock, times(1)).onTestEnd(fixture);
verifyNoMoreInteractions(testListenerMock);
}

@Test(expectedExceptions = TestCaseFailedException.class)
public void testTestListenerEventsWithFailedTestResult() {
TestAction testActionMock = mock();
doThrow(CitrusRuntimeException.class).when(testActionMock).execute(context);
fixture.addTestAction(testActionMock);
TestListener testListenerMock = mock();
context.getTestListeners().addTestListener(testListenerMock);

fixture.doExecute(context);
fixture.finish(context);

verify(testListenerMock, times(1)).onTestStart(fixture);
verify(testListenerMock, times(1)).onAfterSequenceBeforeTest(fixture);
verify(testListenerMock, times(1)).onTestFinish(fixture);
verify(testListenerMock, times(1)).onFinalActionsEnd(fixture);
verify(testListenerMock, times(1)).onTestFailure(fixture, fixture.getTestResult().getCause());
verify(testListenerMock, times(1)).onTestEnd(fixture);
verifyNoMoreInteractions(testListenerMock);
}

@Test
public void testListenerEventOnTestSkipped() {
TestCaseMetaInfo testCaseMetaInfoMock = new TestCaseMetaInfo();
testCaseMetaInfoMock.setStatus(Status.DISABLED);
fixture.setMetaInfo(testCaseMetaInfoMock);
TestListener testListenerMock = mock();
context.getTestListeners().addTestListener(testListenerMock);

fixture.doExecute(context);
fixture.finish(context);

verify(testListenerMock, times(1)).onTestSkipped(fixture);
verifyNoMoreInteractions(testListenerMock);
}

@Test
public void testExecutionWithVariables() {
fixture.setName("MyTestCase");
Expand Down

0 comments on commit 32f2a48

Please sign in to comment.