[Resolved] Using WebDriver after calling quit()?

Всем привет.
В двух словах попробую объяснить что имею, и что хочу получить. Имею тесты, написанные на Java + TestNG + Maven, CI Hudson, на котором стартует приложение и хаб при старте job-а, а также 8 виртуальных машин, на которых стартуют ноды, цепляющиеся к хабу. Хочу получить стабильное выполнение тестов в несколько потоков. Сейчас возникла проблема с параллельностью. А именно, получаю ошибку

org.openqa.selenium.remote.SessionNotFoundException: Session ID is null. Using WebDriver after calling quit()?

Ноды стартуют так:

java -jar selenium-server-standalone-2.43.1.jar -role webdriver -hub http://192.168.123.11:4444/grid/register -port 5562 -browser browserName=firefox

Вот содержимое файла testng.xml:

<suite name = "selenium-tests" parallel = "classes" thread-count = "3">
<test name="test">
    <classes>
        <class name="Class1"/>
        <class name="Class2"/>
        <class name="Class3"/>
        <class name="Class4"/>
        <class name="Class5"/>
    </classes>
</test>

Имеется класс TestBase, в котором аннотированы методы инициализации драйвера и остановки драйвера. Он выглядит так:

public class TestBase {

  protected ApplicationManager app;

  @BeforeClass
  public void init() throws IOException {
    app = new ApplicationManagerImpl();
  }

  @AfterClass
  public void quit() {
    app.quit();
  }

  @AfterMethod
  public void logout() {
    app.logout();
  }

Т.е при старте тестов, в 3 потока, как в примере, у нас должна происходить инициализация драйвера для каждого класса, а после выполнения, сессия должна прибиваться. Что происходит сейчас при таком раскладе: Стартует сборка, я наблюдаю за нодами, и вижу что на 1 из трех потоков создалась новая сессия и начали выполняться тесты, а в двух других потоках сессия создалась и все…Не происходит абсолютно ничего. В результате тесты падают с ошибкой:

    Exception in thread "pool-1-thread-1" org.openqa.selenium.remote.SessionNotFoundException: Session ID is null. Using WebDriver after calling quit()?
Build info: version: '2.43.1', revision: '5163bceef1bc36d43f3dc0b83c88998168a363a0', time: '2014-09-10 09:43:55'
System info: host: 'ci-hudson', ip: '127.0.1.1', os.name: 'Linux', os.arch: 'amd64', os.version: '3.13.0-24-generic', java.version: '1.7.0_72'
Driver info: driver.version: RemoteWebDriver

WebDriverFactory выглядит след. образом:

public class WebDriverFactory {

  private static WebDriver driver;

  public static WebDriver initWebDriver() throws IOException {
    FirefoxProfile firefoxProfile = new FirefoxProfile();
    firefoxProfile.setPreference("print.always_print_silent", true);
    firefoxProfile.setPreference("print.show print progress", false);
    firefoxProfile.setEnableNativeEvents(false);
    DesiredCapabilities capabilities = DesiredCapabilities.firefox();
    capabilities.setBrowserName("firefox");
    capabilities.setCapability("firefox_profile", firefoxProfile.toJson());
    capabilities.setJavascriptEnabled(true);
    driver = new RemoteWebDriver(new URL("http://192.168.123.11:4444/wd/hub"), capabilities);
    driver.manage().window().setPosition(new Point(0, 0));
    driver.manage().window().setSize(new Dimension(1440, 900));
    return driver;
  }

Ума не приложу, как так в самом начале выполнения тестов я уже получаю не действующий драйвер. Ведь quit выполняется в @AfterClass. Подскажите что делаю не так. Спасибо.

Стоит ли в который раз говорить о том, что значит - статическая переменная, и почему это в базовом случае не будет работать в случае с масштабированием?

1 лайк

@ArtOfLife, если вас не затруднит, расскажите пожалуйста.

Из Java Basics: статическая переменная является переменной класса, а не его инстансов. Это значит, что ваш инстанс драйвера будет шариться между всеми сессиями. Тема статических переменных уже обжевана вдоль и поперек на форуме. Наверное, самая распространенная ошибка. На ваш следующий вопрос - как исправить -, ответ - использовать ThreadLocal.

2 лайка

ThreadLocal единственное решение в данном случае, или можно как вариант сделать драйвер не статическим и воспользоваться наследованием?

Конечно можно, если у вас будет некий BaseTest - родитель всех тестов, создающий драйвер в @Before.

2 лайка

@ArtOfLife, спасибо за ответы. Попробую двумя вариантами решить вопрос, для практики, после выберу уже С ThreadLocal не приходилось работать.

Если какой-то ответ был вам полезен:

:wink:

1 лайк

@ArtOfLife, выражаю благодарность. Все заработало. Сейчас избавился от статики, все работает как и должно. Еще попробую реализовать с помощью ThreadLocal

я убрал статику но у меня почемуто стал тупить весь процес все окна стали сразу все включатся без очереодность и нормального ответа в интеренета нету можно может есть есть какойт-а маленкий пример как это будет работать

private static final ThreadLocal<WebDriver> DRIVER_CONTAINER = new ThreadLocal<>();

П.С. В следующий раз потрудитесь хотя бы расставить знаки препинания. :wink: