Skip to content

UI 自动化测试

Since 2.2.34

UI 测试框架在真实 Minecraft 客户端中运行场景:创建独立世界、打开真实 UI、通过普通 Screen 路径发送输入、等待服务端同步、记录断言,并输出截图和报告。

由 LDLib2 UI 自动化场景打开的贪吃蛇 HUD
真实 snake_hud 场景生成的截图。测试框架在客户端中打开此 HUD、操作控件,并将图片与 report.txtreport.json 一并输出。

1. 注册场景

场景放入 src/main/java,不要放在 src/test,并注册到仅客户端的场景 registry。

java
@LDLRegisterClient(name = "furnace_ui", group = "mymod", registry = UIScenario.REGISTRY,
        environment = RegistrationEnvironment.DEV_ONLY)
public class FurnaceUiScenario implements UIScenario {
    private static final BlockPos POS = new BlockPos(8, 65, 8);

    @Override
    public void configure(ScenarioOptions options) {
        options.tags("machine").guiScale(3);
    }

    @Override
    public void define(ScenarioBuilder s) {
        s.clearArea(POS, 2)
         .setBlock(POS, MyBlocks.FURNACE.get())
         .awaitClientBlockEntity(POS)
         .useBlock(POS)
         .awaitScreen(ModularUIContainerScreen.class)
         .awaitModularUI()
         .click("#btn_start")
         .waitForTextContains("#status_label", "Burning")
         .screenshot("running")
         .teardown("close", ctx -> ctx.requirePlayer().closeContainer());
    }
}

RegistrationEnvironment.DEV_ONLY 确保场景不会进入生产构建。

2. 运行

text
gradlew runClient -PldTest=furnace_ui
选项作用
-PldTest=all运行所有已注册场景。
-PldTest=name1,name2运行指定场景。
-PldTest=group:mymod / tag:fast / regex:.*_ui按 group、tag 或名称模式选择。
-PldTestKeepOpen保持客户端打开,便于迭代。
-PldTestGuiScale=3设置整个运行的 GUI scale。
-PldTestInputMode=REAL使用物理鼠标;需要前台焦点。

报告写入 build/ldlib2-uitest/report.jsonreport.txtscreenshots/verifyUiTest 会在 runClient 后执行;缺少报告也会失败。

快速迭代时,使用 -PldTestKeepOpen,然后在游戏内执行 /ldlib2_autotest list/ldlib2_autotest run furnace_ui

3. 编写可靠步骤

目标常用方法
准备世界setBlockclearAreawithBlockEntitygiveItem
打开 UIopenScreenopenModularUIuseBlockawaitScreenawaitModularUI
交互hoverclickdragscrolltypeIntokey
等待framestickswaitUntilwaitForTextwaitForSync
断言checkcheckTextcheckVisiblecheckValuecheckBounds
截图screenshotscreenshotElement

目标使用 LDLib2 CSS 选择器:标签名、.class#id、后代和子选择器以及状态伪类。优先使用稳定 ID,例如 #btn_start。不支持选择器列表、属性选择器和 :nth-child;这些场景使用 ctx.query(...)

后台运行

默认合成输入不夺取焦点也不移动物理鼠标。只有测试操作系统级行为时才用 REAL;运行期间框架还会阻止意外 OS 输入。

等待状态,不等待任意帧数

每个 builder step 在一帧中运行,但游戏和数据绑定 UI 可能每秒只更新 20 tick。优先使用 waitForSyncwaitForTextwaitUntil,不要依赖任意帧延迟。

Released under the MIT License.