You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Serenity BDD Java中实现多条件Check分支(类似if/elseif)

Serenity BDD Screenplay多条件分支(else if)实现方案

Serenity BDD原生的Check类仅支持单条件的if/else结构,要实现多条件分支(类似else if),可以通过以下几种方式解决:

方案1:嵌套原生Check类

直接在otherwise块中嵌套另一个Check,这是最简便的方式,无需额外代码:

and(theActorInTheSpotlight()).attemptsTo(
    Check.whether(Presence.of(PaginaBizagiCTAAperturaCuenta.A_TIT_INF_CLIENTE.waitingForNoMoreThan(Duration.ofSeconds(3))))
        .andIfSo(
            // 第一个条件满足时执行的动作
            Ensure.that(PaginaBizagiCTAAperturaCuenta.A_TIT_INF_CLIENTE).isDisplayed(),
            Click.on(PaginaBizagiCTAAperturaCuenta.BTN_CONTINUE)
        )
        .otherwise(
            Check.whether(Presence.of(PaginaBizagiCTAAperturaCuenta.ANOTHER_KEY_ELEMENT.waitingForNoMoreThan(Duration.ofSeconds(3))))
                .andIfSo(
                    // 第二个条件满足时执行的动作
                    Ensure.that(PaginaBizagiCTAAperturaCuenta.ANOTHER_KEY_ELEMENT).isDisplayed(),
                    Enter.theValue("test").into(PaginaBizagiCTAAperturaCuenta.INPUT_FIELD)
                )
                .otherwise(
                    // 默认分支动作
                    Ensure.that(PaginaBizagiCTAAperturaCuenta.DEFAULT_PAGE).isDisplayed(),
                    Navigate.to("https://your-default-url.com")
                )
        )
);

优缺点:无需额外代码,适合2-3个分支的场景;分支过多时会导致代码缩进层级过深,可读性下降。

方案2:自定义多条件分支工具类

封装一个支持链式调用的多条件检查类,让代码结构更清晰:

1. 定义工具类

import net.serenitybdd.screenplay.Actor;
import net.serenitybdd.screenplay.Performable;

import java.util.ArrayList;
import java.util.List;

public class MultiConditionCheck {
    private final List<ConditionActionPair> conditionActions = new ArrayList<>();
    private Performable defaultAction;

    private MultiConditionCheck() {}

    public static MultiConditionCheck when(Condition condition) {
        MultiConditionCheck check = new MultiConditionCheck();
        check.conditionActions.add(new ConditionActionPair(condition, null));
        return check;
    }

    public MultiConditionCheck then(Performable... actions) {
        ConditionActionPair lastPair = conditionActions.get(conditionActions.size() - 1);
        lastPair.actions = actions;
        return this;
    }

    public MultiConditionCheck otherwiseIf(Condition condition) {
        conditionActions.add(new ConditionActionPair(condition, null));
        return this;
    }

    public Performable otherwise(Performable... actions) {
        this.defaultAction = Performable.where("执行默认动作", actions);
        return actor -> {
            for (ConditionActionPair pair : conditionActions) {
                if (pair.condition.test(actor)) {
                    actor.attemptsTo(pair.actions);
                    return;
                }
            }
            if (defaultAction != null) {
                actor.attemptsTo(defaultAction);
            }
        };
    }

    @FunctionalInterface
    public interface Condition {
        boolean test(Actor actor);
    }

    private static class ConditionActionPair {
        private final Condition condition;
        private Performable[] actions;

        public ConditionActionPair(Condition condition, Performable[] actions) {
            this.condition = condition;
            this.actions = actions;
        }
    }
}

2. 使用工具类

and(theActorInTheSpotlight()).attemptsTo(
    MultiConditionCheck.when(actor -> 
            Presence.of(PaginaBizagiCTAAperturaCuenta.A_TIT_INF_CLIENTE.waitingForNoMoreThan(Duration.ofSeconds(3))).test(actor)
        )
        .then(
            Ensure.that(PaginaBizagiCTAAperturaCuenta.A_TIT_INF_CLIENTE).isDisplayed(),
            Click.on(PaginaBizagiCTAAperturaCuenta.BTN_CONTINUE)
        )
        .otherwiseIf(actor -> 
            Presence.of(PaginaBizagiCTAAperturaCuenta.ANOTHER_KEY_ELEMENT.waitingForNoMoreThan(Duration.ofSeconds(3))).test(actor)
        )
        .then(
            Ensure.that(PaginaBizagiCTAAperturaCuenta.ANOTHER_KEY_ELEMENT).isDisplayed(),
            Enter.theValue("test").into(PaginaBizagiCTAAperturaCuenta.INPUT_FIELD)
        )
        .otherwise(
            Ensure.that(PaginaBizagiCTAAperturaCuenta.DEFAULT_PAGE).isDisplayed(),
            Navigate.to("https://your-default-url.com")
        )
);

优缺点:代码结构清晰,链式调用符合Screenplay风格;需要维护额外的工具类,适合频繁使用多条件分支的项目。

方案3:直接用Lambda表达式处理分支

通过Performable.where直接编写分支逻辑,灵活性最高:

and(theActorInTheSpotlight()).attemptsTo(
    Performable.where("处理多条件分支", actor -> {
        boolean firstCondition = Presence.of(PaginaBizagiCTAAperturaCuenta.A_TIT_INF_CLIENTE.waitingForNoMoreThan(Duration.ofSeconds(3))).test(actor);
        boolean secondCondition = Presence.of(PaginaBizagiCTAAperturaCuenta.ANOTHER_KEY_ELEMENT.waitingForNoMoreThan(Duration.ofSeconds(3))).test(actor);

        if (firstCondition) {
            actor.attemptsTo(
                Ensure.that(PaginaBizagiCTAAperturaCuenta.A_TIT_INF_CLIENTE).isDisplayed(),
                Click.on(PaginaBizagiCTAAperturaCuenta.BTN_CONTINUE)
            );
        } else if (secondCondition) {
            actor.attemptsTo(
                Ensure.that(PaginaBizagiCTAAperturaCuenta.ANOTHER_KEY_ELEMENT).isDisplayed(),
                Enter.theValue("test").into(PaginaBizagiCTAAperturaCuenta.INPUT_FIELD)
            );
        } else {
            actor.attemptsTo(
                Ensure.that(PaginaBizagiCTAAperturaCuenta.DEFAULT_PAGE).isDisplayed(),
                Navigate.to("https://your-default-url.com")
            );
        }
    })
);

优缺点:完全自定义逻辑,适合复杂条件判断;代码风格偏向命令式,和Screenplay的声明式风格略有差异。

内容的提问来源于stack exchange,提问作者Francesco Tufano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 16:22:54