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

Java+TestNG疑问:@BeforeTest初始化变量无法在第二个测试类访问

TestNG @BeforeTest 引发空指针异常的原因解析

问题场景

项目代码结构

  1. 页面类继承关系
    抽象类BasePage:
abstract public class BasePage {
    public String str;
    public BasePage(){
        System.out.println("Constructor class: BasePage");
    }
    public void doSomething(){
        System.out.println(str);
    }
}

PageOne实现类:

public class PageOne extends BasePage{
    public PageOne(String strP1){
        this.str = strP1;
        System.out.println("Constructor class: PageOne = " + this.toString());
    }
}

PageTwo实现类:

public class PageTwo extends BasePage{
    public PageTwo(String strP2){
        this.str = strP2;
        System.out.println("Constructor class: PageTwo = " + this.toString());
    }
}
  1. 测试类继承关系
    抽象类BaseTest:
abstract public class BaseTest {
    PageOne p1;
    PageTwo p2;
    @BeforeTest
    public void setUp(){
        System.out.println("BEFORE TEST in BaseTest: create p1 and p2");
        p1 = new PageOne(); // 注:此处实际会编译报错,PageOne无无参构造方法
        p2 = new PageTwo(); // 同上
        System.out.println("***** BEFORE *****");
    }
}

TestOne测试类:

public class TestOne extends BaseTest{
    public TestOne(){
        System.out.println("Constructor class: TestOne");
    }
    @Test
    public void testDoSomething(){
        p1.doSomething();
        p2.doSomething();
    }
}

TestTwo测试类:

public class TestTwo extends BaseTest{
    public TestTwo(){
        System.out.println("Constructor class: TestTwo");
    }
    @Test
    public void testDoSomething(){
        p1.doSomething();
        p2.doSomething();
    }
}
  1. TestNG配置文件testng.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
    <test verbose="2" preserve-order="true" name="test1">
        <classes>
            <class name="org.example.tests.TestOne"/>
            <class name="org.example.tests.TestTwo"/>
        </classes>
    </test>
</suite>

运行问题

执行后TestTwo抛出空指针异常:

java.lang.NullPointerException: Cannot invoke "org.example.pages.PageOne.doSomething()" because "this.p1" is null

控制台显示@BeforeTest仅执行一次,TestTwo的p1、p2未初始化。

原因解析

核心问题是TestNG中@BeforeTest的作用域规则:

  • @BeforeTest注解的方法,作用域是<test>标签级别——在整个<test>标签下的所有测试类执行前,只会运行一次。
  • 每个测试类(TestOne、TestTwo)会被TestNG创建独立的实例。BaseTest中的p1、p2是实例变量,仅属于当前测试类实例。
  • 当@BeforeTest的setUp方法执行时,它依附在第一个被加载的测试类实例(此处为TestOne)上运行,初始化的是TestOne实例的p1、p2。而TestTwo的实例从未执行过setUp方法,它的p1、p2始终是默认的null,调用方法自然抛出空指针。

为什么@BeforeClass/@BeforeMethod可以解决

  • @BeforeClass:作用域是测试类级别,每个测试类实例创建完成后执行一次。TestOne和TestTwo各自的实例都会触发setUp,初始化自己的p1、p2。
  • @BeforeMethod:作用域是测试方法级别,每个@Test方法执行前执行一次,同样会为每个测试方法对应的实例完成初始化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 18:32:51