Appium中driver.startActivity()替代方案及空指针异常问题咨询
问题描述
环境:Appium 2.2.3、Java JDK 17.05、Appium Java Client 9.0.0、TestNG 7.8.0
运行以下代码时触发空指针异常,现寻求该代码的替代方案,同时需要能在同一个类中运行多个@Test方法的App包名和Activity配置方式:
原代码:
Activity activity = new Activity("com.androidsample.generalstore", "com.androidsample.generalstore.MainActivity"); driver.startActivity(activity);
在@BeforeMethod中尝试的代码:
@BeforeMethod (alwaysRun=true) public void setActivity() { Activity activity = new Activity("com.androidsample.generalstore", "com.androidsample.generalstore.MainActivity"); driver.startActivity(activity); }
报错信息:
java.lang.NullPointerException: 无法调用"pageObjects.android.FormPage.setActivity()",因为"this.formPage"为null at testCases.eCommerce_tc_2.preSetup(eCommerce_tc_2.java:18) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139) at org.testng.internal.invokers.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:69) at org.testng.internal.invokers.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:390) at org.testng.internal.invokers.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:325) at org.testng.internal.invokers.TestInvoker.runConfigMethods(TestInvoker.java:810) at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:577) at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:227) at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:50) at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:957) at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:200) at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:148) at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:128) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.testng.TestRunner.privateRun(TestRunner.java:848) at org.testng.TestRunner.run(TestRunner.java:621) at org.testng.SuiteRunner.runTest(SuiteRunner.java:443) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:437) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:397) at org.testng.SuiteRunner.run(SuiteRunner.java:336) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1280) at org.testng.TestNG.runSuitesLocally(TestNG.java:1200) at org.testng.TestNG.runSuites(TestNG.java:1114) at org.testng.TestNG.run(TestNG.java:1082) at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115) at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
解决方案
先修复空指针异常
报错核心是this.formPage未初始化就被调用,需在调用formPage.setActivity()前完成实例化:
@BeforeMethod(alwaysRun = true) public void preSetup() { // 先初始化page对象 formPage = new FormPage(driver); // 再执行相关操作 formPage.setActivity(); }
配置App包名和Activity的替代方式
方式1:Driver初始化时通过Desired Capabilities指定(全局生效)
创建Driver实例时直接配置appPackage和appActivity,所有@Test方法启动时都会自动打开目标页面:
@BeforeClass(alwaysRun = true) public void setupDriver() throws MalformedURLException { DesiredCapabilities caps = new DesiredCapabilities(); caps.setCapability("platformName", "Android"); caps.setCapability("appium:deviceName", "你的设备名称"); caps.setCapability("appium:appPackage", "com.androidsample.generalstore"); caps.setCapability("appium:appActivity", "com.androidsample.generalstore.MainActivity"); // 其他必要配置,如automationName等 driver = new AndroidDriver(new URL("http://localhost:4723/wd/hub"), caps); }
方式2:使用AppiumOptions配置(Appium 2.x推荐)
Appium 2.x官方更推荐用AppiumOptions替代Desired Capabilities,写法更简洁:
@BeforeClass(alwaysRun = true) public void setupDriver() throws MalformedURLException { AppiumOptions options = new AppiumOptions(); options.setPlatformName("Android"); options.setDeviceName("你的设备名称"); options.setAppPackage("com.androidsample.generalstore"); options.setAppActivity("com.androidsample.generalstore.MainActivity"); // 其他配置 driver = new AndroidDriver(new URL("http://localhost:4723/wd/hub"), options); }
方式3:@BeforeMethod中重置App并启动Activity(用例独立状态)
如果每个@Test需要独立的App初始状态,可在@BeforeMethod中重置App后再启动目标Activity:
@BeforeMethod(alwaysRun = true) public void resetAndLaunch() { // 重置App到初始状态 driver.resetApp(); // 启动指定Activity Activity activity = new Activity("com.androidsample.generalstore", "com.androidsample.generalstore.MainActivity"); driver.startActivity(activity); // 确保page对象已初始化 if (formPage == null) { formPage = new FormPage(driver); } }
方式4:通过adb命令启动Activity(绕过Appium API)
如果startActivity方法存在问题,可直接执行adb命令启动目标页面:
@BeforeMethod(alwaysRun = true) public void launchViaAdb() { try { // 执行adb启动命令 Runtime.getRuntime().exec("adb shell am start -n com.androidsample.generalstore/.MainActivity"); // 等待页面加载 Thread.sleep(2000); } catch (IOException | InterruptedException e) { e.printStackTrace(); } }
内容的提问来源于stack exchange,提问作者Burhan Guvenc
相关产品推荐
相关产品推荐

