Java+TestNG疑问:@BeforeTest初始化变量无法在第二个测试类访问
TestNG @BeforeTest 引发空指针异常的原因解析
问题场景
项目代码结构
- 页面类继承关系
抽象类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()); } }
- 测试类继承关系
抽象类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(); } }
- 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
相关产品推荐
相关产品推荐

