serenity-bdd / serenity-core

Serenity BDD is a test automation library designed to make writing automated acceptance tests easier, and more fun.
http://serenity-bdd.info
Other
722 stars 518 forks source link

Serenity BDD with maven: the "Ensure.that" assertion is not working, causes error: error and.thucydides.core.steps.step eventbus - current listener is null java.lang.exception: #3581

Open xyuste opened 1 day ago

xyuste commented 1 day ago

What happened?

I am using Serenity BDD version 4.2.8 with cucumber junit5, in the runner I am using: @RunWith(CucumberWithSerenity.class) I am using the following depedencies: serenity-core, serenity-junit5, serenity-screenplay, serenity-ensure, serenity-cucumber And when I try to use the "Ensure.that" assertion: actor.attemptsTo(Ensure.that(intMessageCount).isNotEqualTo(0));

The following error is displayed in the console: 15:02:36.140 [main] ERROR n.thucydides.core.steps.StepEventBus - CurrentListener is null java.lang.Exception: Stack trace at java.base/java.lang.Thread.dumpStack(Thread.java:1383) at net.thucydides.core.steps.StepEventBus.getBaseStepListener(StepEventBus.java:212) at net.serenitybdd.screenplay.Actor.thisIsAnExceptionBubblingUpFromAPreviousFailure(Actor.java:293) at net.serenitybdd.screenplay.Actor.perform(Actor.java:281) at net.serenitybdd.screenplay.Actor.attemptsTo(Actor.java:215) at net.serenitybdd.screenplay.Actor.attemptsTo(Actor.java:222) at starter.tasks.SendMessagesToRabbitMQ.performAs(SendMessagesToRabbitMQ.java:74) at starter.tasks.SendMessagesToRabbitMQ$ByteBuddy$m7jmgUsJ.performAs$accessor$lw4VlG32(Unknown Source) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at net.thucydides.core.steps.StepInterceptor.invokeMethod(StepInterceptor.java:524) at net.thucydides.core.steps.StepInterceptor.executeTestStepMethod(StepInterceptor.java:504) at net.thucydides.core.steps.StepInterceptor.runTestStep(StepInterceptor.java:476) at net.thucydides.core.steps.StepInterceptor.runOrSkipMethod(StepInterceptor.java:218) at net.thucydides.core.steps.StepInterceptor.testStepResult(StepInterceptor.java:205) at net.thucydides.core.steps.StepInterceptor.intercept(StepInterceptor.java:93) at net.thucydides.core.steps.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:51) at starter.tasks.SendMessagesToRabbitMQ$ByteBuddy$m7jmgUsJ.performAs(Unknown Source) at net.serenitybdd.screenplay.Actor.performTask(Actor.java:299) at net.serenitybdd.screenplay.Actor.perform(Actor.java:274) at net.serenitybdd.screenplay.Actor.attemptsTo(Actor.java:215) at net.serenitybdd.screenplay.Actor.attemptsTo(Actor.java:222) at starter.stepdefinitions.SearchOnDuckDuckGoStepDefinitions.the_actor_starts_the_delivery_for_match_with_a_poll_interval_of_seconds(SearchOnDuckDuckGoStepDefinitions.java:59) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at io.cucumber.java.Invoker.doInvoke(Invoker.java:66) at io.cucumber.java.Invoker.invoke(Invoker.java:24) at io.cucumber.java.AbstractGlueDefinition.invokeMethod(AbstractGlueDefinition.java:47) at io.cucumber.java.JavaStepDefinition.execute(JavaStepDefinition.java:29) at io.cucumber.core.runner.CoreStepDefinition.execute(CoreStepDefinition.java:66) at io.cucumber.core.runner.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:62) at io.cucumber.core.runner.ExecutionMode$1.execute(ExecutionMode.java:10) at io.cucumber.core.runner.TestStep.executeStep(TestStep.java:81) at io.cucumber.core.runner.TestStep.run(TestStep.java:53) at io.cucumber.core.runner.PickleStepTestStep.run(PickleStepTestStep.java:51) at io.cucumber.core.runner.TestCase.run(TestCase.java:84) at io.cucumber.core.runner.Runner.runPickle(Runner.java:75) at io.cucumber.core.runtime.Runtime.lambda$executePickle$6(Runtime.java:107) at io.cucumber.core.runtime.CucumberExecutionContext.lambda$runTestCase$5(CucumberExecutionContext.java:136) at io.cucumber.core.runtime.RethrowingThrowableCollector.executeAndThrow(RethrowingThrowableCollector.java:23) at io.cucumber.core.runtime.CucumberExecutionContext.runTestCase(CucumberExecutionContext.java:136) at io.cucumber.core.runtime.Runtime.lambda$executePickle$7(Runtime.java:107) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at io.cucumber.core.runtime.Runtime$SameThreadExecutorService.execute(Runtime.java:235) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118) at io.cucumber.core.runtime.Runtime.lambda$runFeatures$3(Runtime.java:89) at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) at java.base/java.util.stream.SliceOps$1$1.accept(SliceOps.java:199) at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1632) at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:127) at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:502) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:488) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) at io.cucumber.core.runtime.Runtime.runFeatures(Runtime.java:90) at io.cucumber.core.runtime.Runtime.lambda$run$0(Runtime.java:78) at io.cucumber.core.runtime.CucumberExecutionContext.lambda$runFeatures$6(CucumberExecutionContext.java:147) at io.cucumber.core.runtime.CucumberExecutionContext.execute(CucumberExecutionContext.java:162) at io.cucumber.core.runtime.CucumberExecutionContext.runFeatures(CucumberExecutionContext.java:145) at io.cucumber.core.runtime.Runtime.run(Runtime.java:78) at io.cucumber.core.cli.Main.run(Main.java:87) at cucumber.api.cli.Main.run(Main.java:30) at cucumber.api.cli.Main.main(Main.java:15)

Although the application continues and the cucumber scenario is finished with error. What I can use the Ensure engine??? Thanks Xavier

What did you expect to happen?

I want to use correctly the "Ensure" dependency

Serenity BDD version

4.2.8

JDK version

openjdk 11.0.11

Execution environment

windows 11 the test is not focused in the web we are validating that a backend core is working correctly, the input is in a RabbitMQ queue.

How to reproduce the bug.

The pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0
<groupId>XXXX</groupId>
<artifactId>XXXX</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Sample Serenity BDD project using Cucumber</name>

 <properties>
    <serenity.version>4.2.8</serenity.version>
    <junit5.version>5.11.3</junit5.version>
    <junit.version>4.13.2</junit.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <encoding>UTF-8</encoding>
    <tags></tags>
    <webdriver.base.url></webdriver.base.url>
</properties>
<dependencies>
    <dependency>
        <groupId>net.serenity-bdd</groupId>
        <artifactId>serenity-core</artifactId>
        <version>${serenity.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>net.serenity-bdd</groupId>
        <artifactId>serenity-junit5</artifactId>
        <version>${serenity.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>net.serenity-bdd</groupId>
        <artifactId>serenity-screenplay</artifactId>
        <version>${serenity.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>net.serenity-bdd</groupId>
        <artifactId>serenity-ensure</artifactId>
        <version>${serenity.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>net.serenity-bdd</groupId>
        <artifactId>serenity-cucumber</artifactId>
        <version>${serenity.version}</version>
    </dependency>        
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.11</version>
    </dependency>
    <!-- JUNIT 5 DEPENDENCY-->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>${junit5.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>${junit5.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <version>${junit5.version}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-core</artifactId>
        <version>3.22.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.rabbitmq</groupId>
        <artifactId>amqp-client</artifactId>
        <version>5.23.0</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.2.5</version>
            <configuration>
                <skip>true</skip>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>3.2.5</version>
            <configuration>
                <includes>
                    <include>**/*Test.java</include>
                    <include>**/Test*.java</include>
                    <include>**/*TestSuite.java</include>
                    <include>**/When*.java</include>
                </includes>
                <systemPropertyVariables>
                    <webdriver.base.url>${webdriver.base.url}</webdriver.base.url>
                    <junit.jupiter.extensions.autodetection.enabled>true</junit.jupiter.extensions.autodetection.enabled>
                </systemPropertyVariables>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.12.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>net.serenity-bdd.maven.plugins</groupId>
            <artifactId>serenity-maven-plugin</artifactId>
            <version>${serenity.version}</version>
            <configuration>
                <tags>${tags}</tags>
                <reports>single-page-html</reports>
            </configuration>
            <executions>
                <execution>
                    <id>serenity-reports</id>
                    <phase>post-integration-test</phase>
                    <goals>
                        <goal>aggregate</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>net.serenity-bdd</groupId>
                    <artifactId>serenity-single-page-report</artifactId>
                    <version>${serenity.version}</version>
                </dependency>
            </dependencies>
        </plugin>
        <plugin>
            <groupId>net.masterthought</groupId>
            <artifactId>maven-cucumber-reporting</artifactId>
            <version>5.7.4</version>
            <executions>
                <execution>
                    <id>execution</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                    <configuration>
                        <projectName>cucumber-jvm-example</projectName>
                        <!-- optional, per documentation set this to "true" to bypass generation
                            of Cucumber Reports entirely, defaults to false if not specified -->
                        <skip>false</skip> 
                        <!-- output directory for the generated report -->
                        <outputDirectory>${project.build.directory}/cucumber/reports</outputDirectory>
                        <!-- optional, defaults to outputDirectory if not specified -->
                        <inputDirectory>${project.build.directory}</inputDirectory>
                        <jsonFiles>
                            <!-- supports wildcard or name pattern -->
                            <param>**/cucumber.json</param>
                        </jsonFiles>
                        <!-- optional, defaults to outputDirectory if not specified -->
                        <classificationDirectory>${project.build.directory}/cucumber/reports</classificationDirectory>
                        <classificationFiles>
                            <param>sample.properties</param>
                            <param>other.properties</param>
                        </classificationFiles> 
                        <!-- optional, set true to fail build on test failures -->
                        <checkBuildResult>false</checkBuildResult>
                    </configuration>
                </execution>
            </executions>
        </plugin>               
    </plugins>
</build>

And stepDefinitions class, I want the cucumber scenario will fail with an error in the Ensure line: @Given("the actor {string} starts the delivery for match {string} with a poll interval of {string} seconds") public void the_actor_starts_the_delivery_for_match_with_a_poll_interval_of_seconds(String actorName, String string2, String string3) {

    Actor actor = OnStage.theActorCalled(actorName);

    actor.whoCan(SendEventMessages.with("aurelia@example.com", "P@ssw0rd"));
    actor.attemptsTo(SendMessagesToRabbitMQ.withCredentials());
    int intMessageCount = 0;
    actor.attemptsTo(Ensure.that(intMessageCount).isNotEqualTo(0));

}

How can we make it happen?

Work on this myself and propose a PR (with Serenity BDD team guidance)

wakaleo commented 1 day ago

Looks like the cucumber scenarios are not being run with the Serenity runner.

xyuste commented 1 day ago

Hi, My runner class: import io.cucumber.junit.CucumberOptions; import net.serenitybdd.cucumber.CucumberWithSerenity; import org.junit.runner.RunWith;

@RunWith(CucumberWithSerenity.class) @CucumberOptions( plugin = {"pretty", "json:target/result/cucumber.json", "junit:target/cucumber-junit-report"}, features = "src/test/resources/features" ) public class CucumberTestSuite { }

Really, some Serenity BDD command are executed correctly, the problem in only in the Ensure.that, because the previous command in the stepDefinition as working as expected:

@Given("the actor {string} starts the delivery for match {string} with a poll interval of {string} seconds") public void the_actor_starts_the_delivery_for_match_with_a_poll_interval_of_seconds(String actorName, String string2, String string3) {

    Actor actor = OnStage.theActorCalled(actorName);

    actor.whoCan(SendEventMessages.with("aurelia@example.com", "P@ssw0rd"));
    actor.attemptsTo(SendMessagesToRabbitMQ.withCredentials());
    int intMessageCount = 0;
    actor.attemptsTo(Ensure.that(intMessageCount).isNotEqualTo(0));

I have noticed that by changing the call "Ensure.that" at the stepDefinition class level, the cucumber scenario is now failing, and after that information appears the following error trace:

Scenarios (1 failed) 3 Steps (1 failed, 2 skipped) 0m3.888s

java.lang.NullPointerException: No BaseStepListener has been registered - are you running your test using the Serenity runners? at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:922) at net.thucydides.core.steps.StepEventBus.getBaseStepListener(StepEventBus.java:215) at net.serenitybdd.screenplay.Actor.thisIsAnExceptionBubblingUpFromAPreviousFailure(Actor.java:293) at net.serenitybdd.screenplay.Actor.perform(Actor.java:281) at net.serenitybdd.screenplay.Actor.attemptsTo(Actor.java:215) at net.serenitybdd.screenplay.Actor.attemptsTo(Actor.java:222) at starter.stepdefinitions.SearchOnDuckDuckGoStepDefinitions.the_actor_starts_the_delivery_for_match_with_a_poll_interval_of_seconds(SearchOnDuckDuckGoStepDefinitions.java:29) at ✽.the actor "dummy fsp" starts the delivery for match "1" with a poll interval of "45" seconds(file:///C:/AutoXXXXProjects/XXXXX/src/test/resources/features/search/search_by_keyword.feature:4)

What I can do to allow that the cucumber scenario uses the Serenity runner? Many thanks Xavier