0

I've updated my Cucumber version to 5.4.2 and this piece of code stopped working due to a Inconvertible types; cannot cast 'io.cucumber.java.Scenario' to 'cucumber.runtime.ScenarioImpl' error.

  Field field = FieldUtils.getField((scenario).getClass(), "stepResults", true); 

Any way I could get it back to working?

This is the whole piece of code as per this SO post

private static String logError(Scenario scenario) {

    Field field = FieldUtils.getField((scenario).getClass(), "stepResults", true);

    if (field != null) {
        field.setAccessible(true);
        try {
            ArrayList<Result> results = (ArrayList<Result>) field.get(scenario);
            for (Result result : results) {
                if (result.getErrorMessage() != null)
                    if (result.getErrorMessage().length() >= 10000) {
                        return FAILED_COMMENT + "\n" + result.getErrorMessage().substring(0, 10000);
                    } else {
                        return FAILED_COMMENT + "\n" + result.getErrorMessage();
                    }
            }
        } catch (Exception e) {
            return FAILED_COMMENT;
        }
    }

    return FAILED_COMMENT;
}

Many thanks.

Francislainy Campos
  • 3,462
  • 4
  • 33
  • 81

1 Answers1

0

By using reflection to reach into a frameworks internals you're depending on implementation details. This is a bad practice, when ever the framework changes its implementation your code may break.

Hooks in Cucumber are designed to manipulate the test execution context before and after a scenario. They're not made to report on the test execution itself. Reporting is cross cutting concern and best managed by using the plugin system.

For example:

package com.example;

import io.cucumber.plugin.ConcurrentEventListener;
import io.cucumber.plugin.event.EventPublisher;
import io.cucumber.plugin.event.Result;
import io.cucumber.plugin.event.Status;
import io.cucumber.plugin.event.TestCase;
import io.cucumber.plugin.event.TestCaseFinished;

public class MyTestListener implements ConcurrentEventListener {
    @Override
    public void setEventPublisher(EventPublisher publisher) {
        publisher.registerHandlerFor(TestCaseFinished.class, this::handleTestCaseFinished);
    }

    private void handleTestCaseFinished(TestCaseFinished event) {
        TestCase testCase = event.getTestCase();
        Result result = event.getResult();
        Status status = result.getStatus();
        Throwable error = result.getError();
        String scenarioName = testCase.getName();
        String id = "" + testCase.getUri() + testCase.getLine();
        System.out.println("Testcase " + id + " - " + status.name());
    }
}

When using JUnit 4 and TestNG you can activate this plugin using:

@CucumberOptions(plugin="com.example.MyTestListener")

With JUnit 5 you add it to junit-platform.properties:

cucumber.plugin=com.example.MyTestListener 

Or if you are using the CLI

--plugin com.example.MyTestListener 
M.P. Korstanje
  • 10,426
  • 3
  • 36
  • 58