Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I have cucumber datatable printed in the console output in Java?

E.g. If this is my feature file:

Scenario: Some dummy scenario
    Given that I do something with this datatable:
      | print   | this |
      | and     | this |
    And something else

The output looks like:

Given that I do something with this datatable:
And something else

I was wondering if it is possible to have an output similar to this:

Given that I do something with this datatable:
  | print   | this |
  | and     | this |
And something else

Thank you for your help


Edit: As requested, the details of my setup are exposed bellow.

I am using Java and this is the class responsible for the configuration:

@RunWith(Cucumber.class)
@CucumberOptions(plugin = {"pretty", "html:target/cucumber"},
        monochrome = false,
        glue = {"my.dummy.package"},
        features = {"classpath:dummy.feature"})
public class DummyFT {

    @Test
    public void test() throws IOException {

    }
}

These tests are executed as a separate maven goal. My profile section has:

<profile>
    <id>functional-tests</id>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <configuration>
                    <testSourceDirectory>test/test-functional/java</testSourceDirectory>
                    <includes>
                        <include>**/*FT.java</include>
                    </includes>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</profile>

and the failsafe plugin:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <dependencies>
            <dependency>
                <groupId>org.apache.maven.surefire</groupId>
                <artifactId>surefire-junit47</artifactId>
                <version>${maven.surefire.junit47}</version>
            </dependency>
        </dependencies>
        <executions>
            <execution>
                <goals>
                    <goal>integration-test</goal>
                    <goal>verify</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

And the cucumber dependencies:

<dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-java</artifactId>
    <version>${cucumber.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>io.cucumber</groupId>
    <artifactId>cucumber-junit</artifactId>
    <version>${cucumber.version}</version>
    <scope>test</scope>
</dependency>

Finally, the tests are triggered by running:

mvn failsafe:integration-test -Pfunctional-tests
like image 686
João Matos Avatar asked Oct 23 '25 03:10

João Matos


1 Answers

I noticed that there was no solution to this still and couldn't find one anywhere else. We were able to get this to work using a custom afterStep hook, though we're doing this with cucumber-jvm-groovy so obviously it's a bit different. You should be able to take something like this and convert it to java if you're determined though.

import cucumber.api.PickleStepTestStep
import cucumber.api.TestCase
import cucumber.runner.Scenario
import gherkin.pickles.PickleCell
import gherkin.pickles.PickleRow
import gherkin.pickles.PickleTable
import groovy.util.logging.Log4j
import util.StringHelper

import java.lang.reflect.Field

@Log4j
class CucumberHelper {

    static TestCase getTestCase(Scenario scenario) {
        Field testCaseField = scenario.getClass().getDeclaredField("testCase")
        testCaseField.setAccessible(true)
        (TestCase) testCaseField.get(scenario)
    }

    static PickleStepTestStep getStepObject(TestCase testCase, int stepIndex) {
        (PickleStepTestStep) testCase.getTestSteps()[stepIndex]
    }

    static printDataTables(PickleStepTestStep step, boolean stepPassed) {
        if (stepContainsDataTable(step)) {
            PickleTable table = getDataTable(step)
            printTable(table, stepPassed)
        }
    }

    static private boolean stepContainsDataTable(PickleStepTestStep step) {
        step?.step?.arguments?.any { it instanceof PickleTable }
    }

    static private PickleTable getDataTable(PickleStepTestStep step) {
        step.step.arguments.find { it instanceof PickleTable }
    }

    static private void printTable(PickleTable table, boolean stepPassed) {
        List<Integer> widths = []
        table.rows.each { PickleRow row ->
            row.cells.eachWithIndex { PickleCell cell, int i ->
                int max = widths[i] ?: 0
                int cellWidth = cell.value.length()
                if(cellWidth > max){
                    widths[i] = cellWidth
                }
            }
        }
        table.rows.each { PickleRow row ->
            printRow(row, stepPassed, widths)
        }
    }

    static private void printRow(PickleRow row, boolean stepPassed, List<Integer> columnWidths) {
        String output = '      | '
        row.cells.eachWithIndex { PickleCell cell, int i ->
            output += cell.value.padRight(columnWidths[i]) + ' | '
        }
        println getConsoleColor(stepPassed) + output + StringHelper.ANSI_RESET
    }

    static private String getConsoleColor(boolean stepPassed) {
        stepPassed ? StringHelper.ANSI_GREEN : StringHelper.ANSI_RED
    }

    static void logBeforeStep(PickleStepTestStep step) {
        log.trace "BEFORE STEP:\n\n\t${step.stepText}\n"
    }

    static void logAfterStep(PickleStepTestStep step) {
        log.trace "AFTER STEP:\n\n\t${step.stepText}\n"
    }

}

And the hook:

AfterStep() { Scenario scenario ->
  try {
    TestCase testCase = CucumberHelper.getTestCase(scenario)
    PickleStepTestStep step = CucumberHelper.getStepObject(testCase, scenario.stepResults.size() - 1)

    CucumberHelper.logAfterStep(step)
    CucumberHelper.printDataTables(step, !scenario.isFailed())
  } catch (Throwable t) {
    // ignore, this hook is only for logging
  }
}

(Obviously there's some extra functionality in there for our use cases, but it might help others. The StringHelper just adds unicode characters for coloring the output but you could easily remove that and have it print in standard terminal colors.)

like image 123
ice1080 Avatar answered Oct 25 '25 17:10

ice1080



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!