Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can @Step be dynamic in Allure?

Tags:

allure

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.

like image 360
TicTacFreshMint Avatar asked Oct 15 '25 06:10

TicTacFreshMint


1 Answers

You can create a helper method that will create steps 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
        });
    }
}

Update 2024

Allure now has step API by default. See io.qameta.allure.Allure class.

Allure.step("Enter amount", () -> {
        //do something
});

The docs: https://allurereport.org/docs/junit5-reference/#test-steps

like image 107
Dmitry Baev Avatar answered Oct 19 '25 12:10

Dmitry Baev