Объект WebDriver равен нулю в методе @BeforeTest в тестовом классе

#java #selenium-webdriver #testng #factory #pageobjects

#java #selenium-webdriver #testng #фабрика #pageobjects

Вопрос:

Я использую Page Object Model PageFactory @Factory @DataProvider

У меня есть 6 пользователей для запуска, и дело в том, что я не могу войти к 2 пользователям в одном экземпляре браузера; каждый пользователь может войти только в новый экземпляр браузера.

Итак, я создаю 6 наборов, по одному для каждого пользователя, и запускаю их все одновременно. (Объект driver создается в @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
  

Вот структура проекта :

Поисковик 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 статичным, поскольку я планирую распараллеливать свои тесты.

Ответ №1:

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>
  

Еще одна важная вещь, которую я узнал, заключалась в том, что можно сохранять атрибуты из методов конфигурации, к которым позже можно получить доступ из любых других аннотированных методов.
В моем случае, поскольку я теперь инициализирую свой объект WebDriver в @BeforeSuite, я сохраняю этот объект под атрибутом ‘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");
   }
}