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

如何在Android Appium测试的@BeforeScenario中选择指定appPackage与appActivity

针对多应用测试场景的Capabilities配置优化方案

你当前在@BeforeScenario中通过配置Desired Capabilities来指定启动的App Package和Activity的方案完全可行,尤其是在startActivity因权限限制无法使用的情况下,这确实是最稳妥的替代方案。

不过为了让你的测试框架更灵活地支持多个应用的测试场景,这里有几个实用的优化建议:

1. 抽离应用配置信息,避免硬编码

把每个应用的APP_PACKAGE和APP_ACTIVITY抽成枚举类统一管理,新增应用时不用修改测试逻辑代码,只需要添加新的配置项即可:

// 定义Android应用的枚举类,集中管理所有应用的核心配置
public enum AndroidApp {
    NOTEPAD("com.example.notepad", ".MainActivity"),
    CALCULATOR("com.android.calculator2", ".Calculator"),
    MESSAGES("com.android.mms", ".ui.ConversationList"); // 可按需扩展更多应用

    private final String appPackage;
    private final String appActivity;

    AndroidApp(String appPackage, String appActivity) {
        this.appPackage = appPackage;
        this.appActivity = appActivity;
    }

    // Getter方法
    public String getAppPackage() { return appPackage; }
    public String getAppActivity() { return appActivity; }
}

2. 通过外部参数动态指定要启动的应用

可以通过系统属性、测试标签或者测试上下文来动态传递目标应用,不用每次修改代码里的判断逻辑就能切换不同应用的测试:

修改你的@BeforeScenario方法,比如通过系统属性来指定要测试的应用:

@BeforeScenario
public void beforeScenario() throws MalformedURLException {
    DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
    desiredCapabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.ANDROID);
    desiredCapabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "device");
    desiredCapabilities.setCapability(MobileCapabilityType.UDID, "L2N4C19924005752");

    // 从系统属性获取目标应用,启动测试时可传入 -Dtest.app=CALCULATOR 快速切换
    String targetAppKey = System.getProperty("test.app", "NOTEPAD");
    AndroidApp targetApp = AndroidApp.valueOf(targetAppKey.toUpperCase());

    if (localAndroid) {
        logger.info("Starting local Android app: " + targetApp.name());
        // 从枚举中自动获取对应的Package和Activity
        desiredCapabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, targetApp.getAppPackage());
        desiredCapabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, targetApp.getAppActivity());
    }

    // 其他Capabilities配置保持不变
    desiredCapabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "uiautomator2");
    desiredCapabilities.setCapability(MobileCapabilityType.NO_RESET, true);
    desiredCapabilities.setCapability(MobileCapabilityType.FULL_RESET, false);
    desiredCapabilities.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 300);
    desiredCapabilities.setCapability("unicodeKeyboard", false);
    desiredCapabilities.setCapability("appWaitDuration", 30);
    desiredCapabilities.setCapability("resetKeyboard", false);

    URL url = new URL("http://localhost:4723/wd/hub");
    appiumDriver = new AndroidDriver(url, desiredCapabilities);
    selector = SelectorFactory.createElementHelper(localAndroid ? SelectorType.ANDROID : SelectorType.IOS);
    appiumDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    appiumFluentWait = new FluentWait(appiumDriver)
            .withTimeout(8, TimeUnit.SECONDS)
            .pollingEvery(350, TimeUnit.MILLISECONDS)
            .ignoring(NoSuchElementException.class);
}

3. 适配不同应用的状态重置需求

因为你设置了NO_RESET = true,App的本地状态会被保留。如果不同应用的测试需要干净的初始状态,可以给枚举类添加状态重置配置,动态调整Capabilities:

// 给枚举类新增是否需要重置状态的属性
public enum AndroidApp {
    NOTEPAD("com.example.notepad", ".MainActivity", true), // 需要完全重置
    CALCULATOR("com.android.calculator2", ".Calculator", false); // 保留状态

    private final String appPackage;
    private final String appActivity;
    private final boolean needFullReset;

    AndroidApp(String appPackage, String appActivity, boolean needFullReset) {
        this.appPackage = appPackage;
        this.appActivity = appActivity;
        this.needFullReset = needFullReset;
    }

    // 新增Getter方法
    public boolean isNeedFullReset() { return needFullReset; }
}

// 在配置Capabilities时动态设置
desiredCapabilities.setCapability(MobileCapabilityType.NO_RESET, !targetApp.isNeedFullReset());
desiredCapabilities.setCapability(MobileCapabilityType.FULL_RESET, targetApp.isNeedFullReset());

这样你的测试框架就能更高效地支持多应用的测试场景,后续维护和扩展也会轻松很多。

内容的提问来源于stack exchange,提问作者Silas Hayri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:08:12