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

使用Playwright Java复用Page做PowerApps测试时遇空指针异常

问题分析与解决方案

核心原因

你的NullPointerException是由于测试类中的page变量未被正确初始化,具体原因有两点:

  1. JUnit 4中@BeforeAll修饰的方法必须是static类型,否则该方法不会被执行。你当前的createPage()是非静态方法,导致page始终为null,调用page.navigate()时触发空指针异常。
  2. 调用persistentLogin(true)时如果没有静态导入PersistentLogin类的方法,也会导致编译/执行错误,无法正确获取Page实例。

另外,原PersistentLogin类的实现存在资源泄漏问题:每次调用都会创建新的Playwright实例,未做复用和关闭处理,长期运行会消耗大量资源。

修正步骤

1. 修复测试类的注解与方法调用

改用JUnit 4的@Before(对应每个测试用例执行前初始化),并确保正确调用PersistentLogin的静态方法:

import org.junit.Before;
import org.junit.Test;
import org.junit.AfterClass;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.options.AriaRole;

public class TestsExample {

    // 注意URL必须带http/https协议头
    private String goToUrl = "https://www.example.com";
    private Page page;

    @Before // 每个测试用例执行前初始化Page
    void createPage(){
        // 明确调用PersistentLogin的静态方法
        page = PersistentLogin.getPersistentPage();
    }

    @Test
    public void saveHolidayPeriodFromAdminScreenTest(){
        page.navigate(goToUrl);

        page.frameLocator("#fullscreen-app-host")
             .getByRole(AriaRole.BUTTON, new FrameLocator.GetByRoleOptions().setName("Run as Admin"))
             .click();
        assertThat(page.frameLocator("#fullscreen-app-host").getByText("Preferences - New Summer Leave 2023")).isVisible();
    }

    @AfterClass // 所有测试结束后清理资源
    public static void cleanUp(){
        PersistentLogin.tearDown();
    }
}

2. 优化PersistentLogin类,实现资源复用与管理

将Playwright和BrowserContext改为静态单例,避免重复创建,并添加资源清理方法:

import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
import java.nio.file.Path;
import java.nio.file.Paths;

public class PersistentLogin {

    private static final String USER_DATA_DIR_PATH = "/Users/user/powerAppsTesting/userData";
    private static Playwright playwright;
    private static BrowserContext context;

    // 初始化Playwright与持久化上下文,仅执行一次
    private static void init() {
        if (playwright == null) {
            playwright = Playwright.create();
            BrowserType chromium = playwright.chromium();
            Path userDataDir = Paths.get(USER_DATA_DIR_PATH);
            // 确保用户数据目录存在,不存在则自动创建
            userDataDir.toFile().mkdirs();
            // 初始化持久化上下文
            context = chromium.launchPersistentContext(userDataDir,
                    new BrowserType.LaunchPersistentContextOptions().setHeadless(true));
        }
    }

    // 获取复用的Page实例
    public static Page getPersistentPage() {
        init();
        return context.newPage();
    }

    // 关闭所有资源
    public static void tearDown() {
        if (context != null) {
            context.close();
        }
        if (playwright != null) {
            playwright.close();
        }
    }
}

额外检查点

  • 确保USER_DATA_DIR_PATH对应的目录有读写权限,否则持久化上下文创建失败会返回null。
  • 测试用例中不要手动关闭page,否则后续测试会无法复用上下文;所有资源清理统一在@AfterClass的tearDown()中执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 13:21:24