SuperAPI AI 工具集

testbench-testing

测试与质量

查看项目

更新于 10-16 05:38

技能介绍

用途

该技能用于指导智能体在 Vaadin 25 中编写端到端(end-to-end)浏览器测试,适用场景是用户要求编写端到端测试等任务。TestBench 会在真实浏览器(Chrome、Firefox 等)中运行 Vaadin 应用,并提供 Java 测试 API,让测试以用户的方式与界面交互。它构建于 Selenium 之上,并针对 Vaadin 组件提供高层 API。

何时使用 TestBench(相对于 UI 单元测试)

适合使用端到端 TestBench 测试的场景包括:

  • 关键用户路径——登录、结账、支付流程
  • 客户端行为——JavaScript 功能、自定义 Web 组件
  • 视觉回归——通过截图比对发现非预期的 UI 变化
  • 跨浏览器测试——验证在 Chrome、Firefox、Safari 中的行为
  • 与外部系统集成——SSO、OAuth 流程

其他情况优先使用 UI 单元测试(参见 ui-unit-testing 技能),其速度更快、更不易出现不稳定。

主要能力

核心概念

  • Element:表示 DOM 元素的类,既可为内置 HTML 元素(如 <div>、<span>),也可为 Vaadin Web 组件(如 <vaadin-button>、<vaadin-grid>)。Element 提供组件特有的交互方法。每个 Vaadin 组件都有对应的 Element 类:ButtonElement、TextFieldElement、GridElement、ComboBoxElement 等。
  • ElementQuery:用于在页面上查找元素,通过 $() 方法使用。支持按类型、ID、属性查找,以及嵌套查询与等待元素出现,相关方法包括 id("id")、first()、last()、get(n)、all()、exists()、waitForFirst()、attribute("name", "value")。

编写测试

资料给出两种测试写法:JUnit 5(继承 BrowserTestBase,使用 @BrowserTest 注解)与 JUnit 4(继承 TestBenchTestCase,使用 @Before / @Test / @After)。示例均以登录流程演示:通过 $(TextFieldElement.class).id("username").setValue(...)、$(PasswordFieldElement.class).id("password").setValue(...)、$(ButtonElement.class).id("login").click() 操作组件,再以 assertTrue($(DivElement.class).id("dashboard").exists()) 断言跳转结果。

页面对象(Page Objects)

页面对象封装对特定视图或组件的交互,使测试方法保持整洁可维护;UI 变化时只需更新页面对象,而无需改每个测试。页面对象继承 TestBenchElement 并使用 @Element("tag-name") 注解,例如:

@Element("div")
@Attribute(name = "class", contains = "login-view")
public class LoginViewElement extends TestBenchElement {
    public void login(String username, String password) {
        $(TextFieldElement.class).id("username").setValue(username);
        $(PasswordFieldElement.class).id("password").setValue(password);
        $(ButtonElement.class).id("login").click();
    }

    public boolean isLoginFailed() {
        return $(DivElement.class).attribute("class", "error").exists();
    }
}

在测试中使用页面对象:

@BrowserTest
public void loginSuccess() {
    LoginViewElement loginView = $(LoginViewElement.class).waitForFirst();
    loginView.login("admin", "secret");

    assertTrue($(DashboardViewElement.class).exists());
}

匹配策略:使用 @Attribute 将页面对象匹配到 DOM 元素,可按 class 属性匹配(多值属性用 contains),或使用 Attribute.SIMPLE_CLASS_NAME 按简单类名自动匹配(会移除 Element/PageObject 后缀)。

复杂组件操作

  • Grid:grid.getRowCount() 获取行数,grid.getCell(0, 0).getText() 获取单元格内容,grid.getRow(0).click() 点击行,grid.scrollToRow(50) 滚动到某行。
  • ComboBox:combo.openPopup() 打开下拉,combo.selectByText("Finland") 按文本选择。
  • Dialog:对话框覆盖主内容,通过 $(DialogElement.class).waitForFirst() 获取,再在对话框内部查找按钮并点击确认。

使用方式

  • 不确定具体 API 细节时,使用 Vaadin MCP 工具(search_vaadin_docs)查阅最新文档,并将 vaadin_version 设为 "25"、ui_language 设为 "java"。
  • 文档 MCP 不覆盖 TestBench API 本身。需要精确的 Element/ElementQuery 签名或源码时,应针对 com.vaadin 的 TestBench 构件(如 vaadin-testbench-core)使用 javadoc MCP(mcp__javadoc__*,未加载时可通过 ToolSearch javadoc 查找),而不是从 ~/.m2 解包 jar。

限制与注意事项

  • TestBench 需要商业版 Vaadin 订阅。
  • 资料未提供价格、安装命令、支持的浏览器版本范围等具体信息。

最佳实践(资料所列)

  • 除最简单的测试外都使用页面对象,使测试可读可维护,让测试方法读起来像用户故事。
  • 元素可能不是立即出现时(导航后、异步加载)使用 waitForFirst() 而不是 first()。
  • 为关键组件指定 ID(如 component.setId("login-button")),便于在测试中查找,优先使用 ID 而非位置查询。
  • 端到端测试聚焦关键路径,全面覆盖交给 UI 单元测试;端到端测试应验证旅程,而非每个边界情况。
  • 在 CI 中使用无头浏览器运行测试,Chrome headless 是最可靠的选择。
  • 不要 sleep,要 wait——用 waitForFirst() 或 waitUntil() 替代 Thread.sleep();显式等待更可靠也更快。
  • 每个测试方法只测一个用户旅程;端到端测试成本高,每个测试应覆盖有意义的场景并保持相互独立。