1

Я хочу закрыть браузер после завершения всего теста. Проблема в том, что я не могу закрыть браузер, так как созданный объект ThreadLocal драйвер не распознает драйвер после завершения возвращаемого значения теста.TestNG Закрыть браузер после параллельного тестирования

Ниже мой рабочий код

package demo; 

import java.lang.reflect.Method; 
import org.openqa.selenium.By; 
import org.testng.annotations.AfterMethod; 
import org.testng.annotations.BeforeMethod; 
import org.testng.annotations.DataProvider; 
import org.testng.annotations.Test; 

public class ParallelMethodTest { 
    private static ThreadLocal<dummy> driver; 
    private int input; 
    private int length; 

    @BeforeMethod 
    public void beforeMethod() { 
     System.err.println("Before ID" + Thread.currentThread().getId()); 
     System.setProperty("webdriver.chrome.driver", "chromedriver.exe"); 
     if (driver == null) { 
      driver = new ThreadLocal<dummy>(); 
     } 
     if (driver.get()== null) { 
      driver.set(new dummy()); 
     } 

    } 

    @DataProvider(name = "sessionDataProvider", parallel = true) 
    public static Object[][] sessionDataProvider(Method method) { 
     int len = 12; 

     Object[][] parameters = new Object[len][2]; 
     for (int i = 0; i < len; i++) { 
      parameters[i][0] = i; 
      parameters[i][1]=len; 

     } 
     return parameters; 
    } 

    @Test(dataProvider = "sessionDataProvider") 
    public void executSessionOne(int input,int length) { 
     System.err.println("Test ID---" + Thread.currentThread().getId()); 
     this.input=input; 
     this.length=length; 
     // First session of WebDriver 
     // find user name text box and fill it 
     System.out.println("Parameter size is:"+length); 
     driver.get().getDriver().findElement(By.name("q")).sendKeys(input + ""); 
     System.out.println("Input is:"+input); 

     try { 
      Thread.sleep(5000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

    } 

    @AfterMethod 
    public void afterMethod() { 
    System.err.println("After ID" + Thread.currentThread().getId()); 
    driver.get().close(); 

    } 


} 

package demo; 

import org.openqa.selenium.WebDriver; 
import org.openqa.selenium.chrome.ChromeDriver; 
import org.testng.annotations.AfterClass; 

public class dummy { 

    public WebDriver getDriver() { 
     return newDriver; 
    } 

    public void setNewDriver(WebDriver newDriver) { 
     this.newDriver = newDriver; 
    } 

    private WebDriver newDriver; 

    public dummy() { 
     newDriver = new ChromeDriver(); 
     newDriver.get("https://www.google.co.in/"); 
    } 

    @AfterClass 
    public void close(){ 
     if(newDriver!=null){ 
      System.out.println("In After Class"); 
      newDriver.quit(); 
     } 
    } 
} 

Заранее спасибо.

ответ

0

Это происходит потому, что вы создаете экземпляр драйвера в функции beforeMethod, поэтому он заканчивается после завершения функции.

Итак, когда ваш метод afterMethod начинает получать нуль, поскольку экземпляр webdriver уже уничтожается, поскольку функция beforeMethod уже завершена.

см ниже ссылок: -

http://www.java-made-easy.com/variable-scope.html

What is the default scope of a method in Java?

+0

пожалуйста, найти свой обновленный код. Я инициализировал драйвер в ThreadLocal. я не думаю, что есть проблема с объемом. – manish

0

У вас есть вопрос параллелизма: несколько потоков могут создать ThreadLocal экземпляр, потому что dummy == null может вычисляться true на более чем один поток при запуске в параллельны друг другу. Таким образом, некоторые потоки могут выполнять driver.set(new dummy());, но затем другой поток заменяет driver новым экземпляром ThreadLocal.

По моему опыту это проще и менее подвержен ошибкам, чтобы всегда использовать ThreadLocal как static final, чтобы гарантировать, что несколько объектов доступа к нему (static) и что он определен только один раз (final).

Вы можете увидеть мои ответы на следующие вопросы переполнения стека для связанных деталей и образцов коды:

2

private static ThreadLocal<dummy> driver добавляются на уровне класса. Что происходит, так это то, что вы уже объявили переменную на уровне класса. то есть память уже выделена для него. Несколько потоков просто устанавливают и возвращают значения той же переменной.

Что вам нужно сделать, это создать фабрику, которая вернет экземпляр драйвера на основе параметра, который вы передадите ему. Логика может быть чем угодно, но при использовании примера с общим использованием фабрика будет создавать новый объект и возвращать только если существующий объект не существует. Объявляем и инициализируем драйвер (с завода) в вашем Методы @test

Пример кода для завода будет что-то вроде

static RemoteWebDriver firefoxDriver; 
static RemoteWebDriver someOtherDriver; 


static synchronized RemoteWebDriver getDriver(String browser, String browserVersion, String platform, String platformVersion) 
{ 
if (browser == 'firefox') 
{ 
    if (firefoxDriver == null) 
    { 
       DesiredCapabilities cloudCaps = new DesiredCapabilities(); 
       cloudCaps.setCapability("browser", browser); 
       cloudCaps.setCapability("browser_version", browserVersion); 
       cloudCaps.setCapability("os", platform); 
       cloudCaps.setCapability("os_version", platformVersion); 
       cloudCaps.setCapability("browserstack.debug", "true"); 
       cloudCaps.setCapability("browserstack.local", "true"); 

       firefoxDriver = new RemoteWebDriver(new URL(URL),cloudCaps); 
} 
} 
else 
{ 
if (someOtherDriver == null) 
    { 
       DesiredCapabilities cloudCaps = new DesiredCapabilities(); 
       cloudCaps.setCapability("browser", browser); 
       cloudCaps.setCapability("browser_version", browserVersion); 
       cloudCaps.setCapability("os", platform); 
       cloudCaps.setCapability("os_version", platformVersion); 
       cloudCaps.setCapability("browserstack.debug", "true"); 
       cloudCaps.setCapability("browserstack.local", "true"); 

       someOtherDriver = new RemoteWebDriver(new URL(URL),cloudCaps); 
} 
return someOtherDriver; 
} 
Смежные вопросы