3

I have a Allure step method for a parametrized JUnit 5 and Selenium test which receives a test data object containing all the test data for the parametrized test.

This main step method calls other sub step methods. A sub step is only executed if its argument is not null. Thus I can control the test execution by the test data itself. I check for null in the sub step and not in the main step method because the sub step can be called from any test (I do not want to repeat myself).

Example:

@Step
public void trade(TradeData data) {
    enterAmount(data.getAmount());
    enterCurrency(data.getCurrency());
}

@Step
public void enterAmount(String amount) {
    if (amount != null) {
        // do something
    }
}

@Step
public void enterCurrency(String currency) {
    if (currency != null) {
        // do something
    }
}

In the Allure test report it appears that the sub steps are always executed.

For the above example it always reads like:

trade

enterAmount

enterCurrency

Only if I click on a sub step and see that the argument was null then I can infer that it was not executed. This is not ideal.

Instead I would like that the report displays only the steps which have been executed. Lets assume that only ¨amount¨ is null, then it would look like:

trade

enterCurrency

I can imagine that it would be possible by not using a inflexible @Step annotation and instead calling an Allure method in the if-block to declare the method to be regarded as a step (pseudo code):

public void enterAmount(String amount) {
    if (amount != null) {
        Allure.context().step();
        // do something
    }
}

But is this possible somehow with Allure? I prefer an easy way over a very complicated workaround.

1 Answers1

2

You can create helper method that will create step using Allure Lifecycle API:

public static void step(String name, Runnable runnable) {
    String uuid = UUID.randomUUID().toString();
    StepResult result = new StepResult()
            .withName(name);
    Allure.getLifecycle().startStep(uuid, result);
    try {
        runnable.run();
        Allure.getLifecycle().updateStep(uuid, s -> s.withStatus(Status.PASSED));
    } catch (Throwable e) {
        Allure.getLifecycle().updateStep(uuid, s -> s
                .withStatus(ResultsUtils.getStatus(e).orElse(Status.BROKEN))
                .withStatusDetails(ResultsUtils.getStatusDetails(e).orElse(null)));
        throw e;
    } finally {
        Allure.getLifecycle().stopStep(uuid);
    }
}

and then use it like this:

public void enterAmount(String amount) {
    if (amount != null) {
        step("Enter amount", () -> {
            //do something
        });
    }
}
Dmitry Baev
  • 2,270
  • 1
  • 14
  • 24
  • That might have worked for me, thank you. I think I overlooked the¨startStep¨ method. Shortly after my posting here I had solved it in a different way, but I maybe get back to your method for some cases. My test data objects now have only attributes of type `java.util.Optional`, and I call the sub step methods only if the value is not empty, like this: `data.amount.ifPresent(this::setAmount);` Furthermore I made the sub step private, test behavior can be driven only by the test input data. – TicTacFreshMint Aug 27 '18 at 10:40