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

AndroidDriver截图代码咨询:现有代码触发空指针异常

嘿,我来帮你搞定AndroidDriver的截图捕获问题,还有那个烦人的空指针异常!

AndroidDriver 截图实现&空指针排查方案

首先,先说说你遇到空指针异常(NPE)的大概率原因:

  • 你的AndroidDriver实例在测试失败时已经被提前销毁/置为null了
  • 调用截图逻辑时,没有正确拿到有效的Driver实例
  • 截图要保存的目录不存在,导致文件操作环节出问题

下面是修复后的完整代码示例,我加了详细注释帮你理解:

import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.android.AndroidDriver;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import org.apache.commons.io.FileUtils;

// 可以把这个监听器集成到你的测试类,或者单独作为监听类使用
public class TestFailureScreenshotListener extends TestListenerAdapter {

    // 全局保存Driver实例,确保测试失败时它还处于有效状态
    private AndroidDriver driver;

    // 通过构造方法传入Driver,保证和测试用的是同一个实例
    public TestFailureScreenshotListener(AndroidDriver driver) {
        this.driver = driver;
    }

    @Override
    public void onTestFailure(ITestResult result) {
        super.onTestFailure(result);
        
        // 先做空判断,从根源避免空指针!
        if (driver == null) {
            System.err.println("Driver实例为空,无法捕获截图");
            return;
        }

        if (!result.isSuccess()) {
            // 生成带时间戳的截图文件名,防止重名覆盖
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat formatter = new SimpleDateFormat("dd_MM_yyyy_hh_mm_ss");
            String methodName = result.getMethod().getMethodName();
            String screenshotFileName = methodName + "_fail_" + formatter.format(calendar.getTime()) + ".png";

            // 指定截图保存路径,建议用绝对路径,先确保目录存在
            String screenshotSavePath = "./test-failure-screenshots/";
            File screenshotDir = new File(screenshotSavePath);
            if (!screenshotDir.exists()) {
                screenshotDir.mkdirs(); // 目录不存在就自动创建
            }

            try {
                // AndroidDriver实现了TakesScreenshot接口,直接转换即可
                TakesScreenshot screenshotTaker = (TakesScreenshot) driver;
                File screenshotSource = screenshotTaker.getScreenshotAs(OutputType.FILE);
                // 把临时截图文件复制到指定路径
                FileUtils.copyFile(screenshotSource, new File(screenshotSavePath + screenshotFileName));
                System.out.println("测试失败截图已保存:" + screenshotSavePath + screenshotFileName);
            } catch (IOException e) {
                e.printStackTrace();
                System.err.println("保存截图时出错:" + e.getMessage());
            } catch (ClassCastException e) {
                System.err.println("当前Driver版本不支持截图功能,请检查依赖版本");
            }
        }
    }
}

使用注意事项

  • Driver生命周期管理:确保你的AndroidDriver实例在整个测试周期内有效,不要在测试方法结束后立刻调用quit(),建议放在@AfterSuite或@AfterTest注解的方法中关闭
  • 依赖引入:代码里用到了commons-io处理文件复制,如果是Maven项目,需要在pom.xml中添加依赖:
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
    <scope>test</scope>
</dependency>
  • 监听器注册:可以在测试类上通过@Listeners注解注册,或者在TestNG配置文件testng.xml中配置:
@Listeners(TestFailureScreenshotListener.class)
public class YourAndroidTestClass {
    private AndroidDriver driver;

    @BeforeMethod
    public void setUp() throws MalformedURLException {
        // 初始化AndroidDriver的逻辑,比如配置DesiredCapabilities
        driver = new AndroidDriver(new URL("http://localhost:4723/wd/hub"), yourCapabilities);
        // 如果用构造方法传Driver,要确保监听器拿到同一个实例
        TestFailureScreenshotListener listener = new TestFailureScreenshotListener(driver);
    }
}

内容的提问来源于stack exchange,提问作者shashank shekhar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:17:42