在测试类的@BeforeTest方法中,WebDriver对象为null

问题描述

我正在使用Page Object Model + PageFactory + @Factory + @DataProvider

我有6个用户要运行,但事实是我无法在同一浏览器实例中登录2个用户。每个用户只能登录一个新的浏览器实例。

因此,我创建了6个套件,每个用户一个,然后一次运行所有套件。 (驱动程序对象在@BeforeSuite中创建)
每个套件包含多个测试标签,每个测试标签包含多个类标签。使用@Factory确定类标记数量
我正在以编程方式创建testng.xml。

它看起来像这样:

<suite name="user1">
  <test>
    <classes>
      <class name="SearchPerson" />
      .
      .
      .
      <class name="SearchPerson" />
    </classes>
  </test>

  <test>
    <classes>
      <class name="PrintPerson" />
      .
      .
      .
      <class name="PrintPerson" />
    </classes>
  </test>
</suite>

and similarly 5 more suites for the other 5 users

这是项目结构:

SearchPerson extends TestEngine extends TestBase

TestBase.java

public WebDriver webDriver;

public createChromeDriver(){
  System.setProperty("webdriver.chrome.driver",path to chromedriver.exe);
  webDriver = new ChromeDriver();
}

TestEngine.java

public TestEngine extends TestBase{

  @BeforeSuite
  public void setUp(){
     createChromeDriver();
     webDriver.get("https://www.google.com");
  }

  @DataProvider
  public static Object[][] getTestData(){
     return Object[][]{ {"name1"},{"name2"} };
  }

  @AfterSuite
  public void close(){
     webDriver.quit();
  }

}

我的实际测试-SearchPerson.java

public class SearchPerson extends TestEngine{

  String name;
  Person person;

  @Factory(dataProvider = getTestData,dataProviderClass = TestEngine.class)
  public SearchPerson(String name){
      this.name = name;
  }

  @BeforeTest
  public void initPageObjects(){
     person = new Person(webDriver);
  }

   @Test
   public void setName(){
      person.setName(name);
   }

   @Test
   public void printName(){
      person.printName();
   }
}    

我也不想使我的WebDriver对象成为静态对象,因为我计划并行化测试。

解决方法

TL; DR
1。可以从配置方法中保存属性,以后可以从任何其他带注释的方法中访问属性
2.在@BeforeSuite中创建的对象仅可用于该套件中的第一个测试

在TestNG Google网上论坛问了同样的问题后,我发现@BeforeSuite中创建的对象仅可用于该套件中的第一个测试。

因此,我更改了XML的方式是标签代表用户,而不是标签。

我的新XML如下:

<suite>
  <test name="user1">
    <classes>
      <class name="PrintPerson" />
      ..
      <class name="PrintPerson" />
      <class name="SearchPerson" />
      ..
      <class name="SearchPerson" />
    </classes>
  </test>

  <test name="user2">
    <classes>
      <class name="PrintPerson" />
      ..
      <class name="PrintPerson" />
      <class name="SearchPerson" />
      ..
      <class name="SearchPerson" />
    </classes>
  </test>
</suite>

我学到的另一件重要的事情是,可以从配置方法中保存属性,以后可以从任何其他带注释的方法中访问这些属性。 就我而言,由于我现在在@BeforeSuite中初始化WebDriver对象,因此将该对象保存在属性'webDriver'下

@BeforeSuite
public void beforeSuite(ITestContext testContext){
   driver = new ChromeDriver();   
   testContext.setAttribute("webDriver",driver);
}

并在我的测试类中的@BeforeTest中访问它


class Test1{
   WebDriver driver;
   
   @BeforeTest
   public void beforeTest(ITestContext testContext){
      driver = (WebDriver) testContext.getAttribute("webDriver");
   }

   @Test
   public void testMethod(){
      driver.get("https://www.google.com");
   }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...