使用Serenity Screenplay处理动态Web表格的最佳方法是什么?
使用Serenity Screenplay处理动态Web表格的最佳实践
在Serenity Screenplay模式下,处理动态表格要遵循其「角色-任务-交互-断言」的核心逻辑,相比原生Selenium的直接元素查找,更注重封装和复用性。以下是具体实现步骤:
1. 封装表格元素组件
先把动态表格的元素抽象成页面组件,用Serenity的注解定位目标行/单元格:
import net.serenitybdd.core.pages.PageComponent; import net.serenitybdd.core.pages.WebElementFacade; import org.openqa.selenium.support.FindBy; import java.util.List; public class LeftContainerTable extends PageComponent { // 定位表格第一列的所有单元格,对应你原Selenium代码的XPath @FindBy(xpath = ".//*[@id='leftcontainer']/table/tbody/tr/td[1]") private List<WebElementFacade> tableColumnCells; // 获取所有单元格文本 public List<String> getColumnValues() { return tableColumnCells.stream() .map(WebElementFacade::getText) .toList(); } }
2. 创建任务类封装表格操作
Screenplay中,所有操作都要封装成「任务」,让角色(Actor)去执行:
import net.serenitybdd.screenplay.Actor; import net.serenitybdd.screenplay.Task; import net.thucydides.core.annotations.Step; import static net.serenitybdd.screenplay.Tasks.instrumented; public class FetchTableColumnValues implements Task { private LeftContainerTable leftContainerTable; @Override @Step("{0} 获取表格第一列的所有值") public <T extends Actor> void performAs(T actor) { // 角色访问页面组件 leftContainerTable = actor.recall("currentPage").getPageComponent(LeftContainerTable.class); // 将获取到的值存入角色的内存,供后续断言使用 actor.remember("columnValues", leftContainerTable.getColumnValues()); } // 静态方法用于创建任务实例 public static FetchTableColumnValues fromLeftContainer() { return instrumented(FetchTableColumnValues.class); } }
3. 在测试用例中调用任务
通过Actor执行任务,完成表格数据的获取和验证:
import net.serenitybdd.junit5.SerenityJUnit5Extension; import net.serenitybdd.screenplay.Actor; import net.serenitybdd.screenplay.abilities.BrowseTheWeb; import net.serenitybdd.screenplay.actions.Open; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.openqa.selenium.chrome.ChromeDriver; import static org.assertj.core.api.Assertions.assertThat; import java.util.List; @ExtendWith(SerenityJUnit5Extension.class) public class TableTest { Actor sam = Actor.named("Sam").whoCan(BrowseTheWeb.with(new ChromeDriver())); @Test void should_fetch_table_column_values() { // 打开目标页面 sam.attemptsTo(Open.url("你的目标页面URL")); // 存储当前页面到角色内存,供任务调用 sam.remember("currentPage", sam.abilityTo(BrowseTheWeb.class).getCurrentPage()); // 执行获取表格数据的任务 sam.attemptsTo(FetchTableColumnValues.fromLeftContainer()); // 从角色内存取出数据并断言 List<String> columnValues = sam.recall("columnValues"); assertThat(columnValues).contains("预期值1", "预期值2"); } }
核心优势
- 复用性:表格组件和任务可以在多个测试用例中重复调用
- 可读性:测试代码更贴近自然语言,符合Screenplay的业务场景描述
- 可维护性:元素定位变更时,只需修改组件类,无需改动测试逻辑
内容的提问来源于stack exchange,提问作者sama940
相关产品推荐
相关产品推荐

