Overview
I have different cucumber scenarios and I want to log the test step in BeforeStep in cucumber.
Create a Listener using the TestStepStarted
import io.cucumber.plugin.ConcurrentEventListener;
import io.cucumber.plugin.event.EventHandler;
import io.cucumber.plugin.event.EventPublisher;
import io.cucumber.plugin.event.PickleStepTestStep;
import io.cucumber.plugin.event.TestStepStarted;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ITestStepStarted implements ConcurrentEventListener {
private static final Logger LOGGER = LogManager.getLogger(ITestStepStarted.class);
public EventHandler<TestStepStarted> handler = this::logTestStepName;
@Override
public void setEventPublisher(EventPublisher eventPublisher) {
eventPublisher.registerHandlerFor(TestStepStarted.class, handler);
}
private void logTestStepName(TestStepStarted testStepStarted) {
if(testStepStarted.getTestStep() != null && testStepStarted.getTestStep() instanceof PickleStepTestStep) {
PickleStepTestStep testStep = (PickleStepTestStep) testStepStarted.getTestStep();
LOGGER.info("Step Text: {}", testStep.getStep().getText());
}
}
}
The given code represents a class named ITestStepStarted
that implements the ConcurrentEventListener
interface. Here are the key points about this class:
- The class has a static logger named
LOGGER
from theLogManager
class, which is used for logging purposes. - The class defines an event handler named
handler
of typeEventHandler<TestStepStarted>
. Thehandler
is initialized with a method referencethis::logTestStepName
, which means thelogTestStepName
the method will be invoked when an event of the typeTestStepStarted
occurs. - The class overrides the
setEventPublisher
method from theConcurrentEventListener
interface. Inside this method, it registers thehandler
for events of the typeTestStepStarted
with theeventPublisher
. - The
logTestStepName
method is a private method that takes anTestStepStarted
object as a parameter. It checks if theTestStep
object insidetestStepStarted
is not null and is an instance ofPickleStepTestStep
. If so, it casts theTestStep
toPickleStepTestStep
and performs some operations. - Inside the
logTestStepName
method, the text of the step is retrieved usingtestStep.getStep().getText()
. It is then logged using the logger, providing information about the step text.
In summary, the class ITestCaseStarted
implements an event listener interface, registers an event handler for a specific event type, and captures and logs information about test steps, specifically when they are of type PickleStepTestStep
.
How to use this listener
Add the listener class in your runner file as mentioned below:
@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/test/resources/features",
glue = "com.cucumber.framework.definitions",
plugin = {"io.qameta.allure.cucumber7jvm.AllureCucumber7Jvm",
"com.cucumber.framework.listeners.ITestStepStarted"}
)
public class TestRunner {
}
Output after execution
[INFO ] 2023-07-09 11:23:23 [main] ITestStepStarted - Step Text: given step
[INFO ] 2023-07-09 11:23:23 [main] HooksDemoDefs - given step
[INFO ] 2023-07-09 11:23:23 [main] ITestStepStarted - Step Text: when step
[INFO ] 2023-07-09 11:23:23 [main] HooksDemoDefs - when step
[INFO ] 2023-07-09 11:23:23 [main] ITestStepStarted - Step Text: Then step
[INFO ] 2023-07-09 11:23:23 [main] HooksDemoDefs - Then step
[INFO ] 2023-07-09 11:23:23 [main] ITestStepStarted - Step Text: given step two
[INFO ] 2023-07-09 11:23:23 [main] HooksDemoDefs - given step two
[INFO ] 2023-07-09 11:23:23 [main] ITestStepStarted - Step Text: when step two
[INFO ] 2023-07-09 11:23:23 [main] HooksDemoDefs - when step two
[INFO ] 2023-07-09 11:23:23 [main] ITestStepStarted - Step Text: Then step two
[INFO ] 2023-07-09 11:23:23 [main] HooksDemoDefs - when step two
Conclusion
Note: If you will try to store the step text in a variable and try to do it in BeforeStep then it will not lead to a proper result. The Hook Will be called before this listener So you will get null value for the step text.