Перейти к содержимому

Фотография

Параллельные тесты выполняются в одном окне

Selenium JUnit

  • Авторизуйтесь для ответа в теме
Сообщений в теме: 14

#1 Alemix

Alemix

    Новый участник

  • Members
  • Pip
  • 34 сообщений
  • ФИО:Герасимов Алексей Михайлович

Отправлено 09 января 2019 - 18:15

Здравствуйте, я использую JUnit. Запускаю параллельно в 2 потока выполнение тестов. Открывается 2 браузера, но оба теста выполняются только в одном из-за чего тесты, конечно, валятся. Почему так происходит?

 

driver = new ChromeDriver(options); вызывается перед каждым тестом.

 

Параллельность определяю так:

<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<parallel>methods</parallel>
<threadCountMethods>2</threadCountMethods>
<perCoreThreadCount>false</perCoreThreadCount>

.....


  • 0

#2 BadMF

BadMF

    Специалист

  • Members
  • PipPipPipPipPip
  • 809 сообщений
  • ФИО:Dmitry Petrov

Отправлено 11 января 2019 - 06:53

потому что силениум работает только в активном окне, так как много контролов пользуются абсолютным позиционированием на экране. Если я конечно ничего не путаю. 

 

Если хотите 2 потока, должно быть 2 окружения.


  • 0

#3 sergueik

sergueik

    Постоянный участник

  • Members
  • PipPipPip
  • 166 сообщений
  • ФИО:кузьмин сергей

Отправлено 13 января 2019 - 06:10

посмотрите что у тестов уникельные объекты -  нашел в смоем коде ошибку -  грид, ноды  т.п. -  параллельные тест успешно запускали два хрома каждый открывает сайт  -  но когда нарисовалось оба браузера выясеилось что два паралленых метода пишут в один input (
 

Web Element hash code: 2116447074
Web Element hash code: 2116447074
 

).

Когда б - разные то не collate а когда несколько штук того же то в моем коде ошибка где то thread id теряется.. но на самом то деле все работает


 
@DataProvider(name = "browser-provider", parallel = true)
public Object[][] provide() throws Exception {
return new Object[][] { { "firefox", "input[name*='q']" },
{ "chrome", "input[name='q']" }, };
}
 
@Test(dataProvider = "browser-provider", threadPoolSize = 2)
public void googleSearchTest(String browser, String cssSelector)) {
 
System.err.println("Launching " + browser + (remote ? " remotely" : ""));
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
ChromeOptions chromeOptions = new ChromeOptions();
driver = DriverWrapper.current();
// intended to hashe instances by broswer name +session id - buggy
driver.get(baseURL);
actions = new Actions(driver);
 
driver.findElement( By.cssSelector(cssSelector))));
System.err.println("Web Element hash code: " + element.hashCode());
// один и тот же
element.sendKeys("Тестовое задание");
    // clobber ....
}
 

Прикрепленные файлы

  • Прикрепленный файл  capture.png   386,56К   0 Количество загрузок:
  • Прикрепленный файл  capture2.png   94,83К   0 Количество загрузок:

  • 0

#4 Little_CJIOH

Little_CJIOH

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 515 сообщений
  • ФИО:Власкин Павел
  • Город:Санкт-Петербург


Отправлено 13 января 2019 - 11:49

Потому что силениум работает только в активном окне. 
Два браузера у вас открылось, да, но работать все будет в активном. Если у вас когда-то "получилось" как на второй картинке - то исключительно потому, что второй браузер долго запускался и тесты, фактически, выполнились последовательно.


  • 0

#5 sergueik

sergueik

    Постоянный участник

  • Members
  • PipPipPip
  • 166 сообщений
  • ФИО:кузьмин сергей

Отправлено 14 января 2019 - 01:36

Потому что силениум работает только в активном окне. 
Два браузера у вас открылось, да, но работать все будет в активном. Если у вас когда-то "получилось" как на второй картинке - то исключительно потому, что второй браузер долго запускался и тесты, фактически, выполнились последовательно.

@Little_CJIOH
 

спасибо - у вас есть ссылка на документ где это ограраничение описано подробно -  а  то у меня в проекте  немного задержка с выяснением где объекты не изолированы и мой пример пишет text 2 раза в тот же инпут потому что на двух традах testng переменная одинаковая ... и проверять ваше объяснение скриншота приоритет немного ниже.

 


  • 0

#6 sergueik

sergueik

    Постоянный участник

  • Members
  • PipPipPip
  • 166 сообщений
  • ФИО:кузьмин сергей

Отправлено 17 января 2019 - 01:18

починил свой класс -все нормально вставляет параллельно - 

Прикрепленные файлы


  • 0

#7 Alemix

Alemix

    Новый участник

  • Members
  • Pip
  • 34 сообщений
  • ФИО:Герасимов Алексей Михайлович

Отправлено 17 января 2019 - 02:14

починил свой класс -все нормально вставляет параллельно - 

Может быть, расскажете как починили? Что читали?


  • 0

#8 sergueik

sergueik

    Постоянный участник

  • Members
  • PipPipPip
  • 166 сообщений
  • ФИО:кузьмин сергей

Отправлено 17 января 2019 - 03:24

во первых это testng а не junit

метод сам с собой параллельно и с дата провайдером хард-код прямо в коде (это можно наверное лекго обойти) 

 

	@DataProvider(name = "same-browser", parallel = true)
	public Object[][] provideSameBrowser() throws Exception {
		return new Object[][] {
				{ "chrome", "https://www.google.com/?hl=ru", "input[name*='q']" },
				{ "chrome", "https://www.google.com/?hl=ko", "input[name='q']" }, };
	}

	@Test(enabled = true, dataProvider = "same-browser", threadPoolSize = 2)
	public void googleSearch1Test(String browser, String baseURL,
			String cssSelector) {

...


		DriverWrapper.add(remote ? "remote" : "chrome", capabilities);
		DriverWrapper.setDebug(true);

		System.err.println("Driver inventory: "
				+ DriverWrapper.getDriverInventoryDump().toString());

		WebDriver driver = DriverWrapper.current();
		driver.get(baseURL);
...
		element.sendKeys(searchString  /* + Keys.RETURN */);
		element = wait.until(
				ExpectedConditions.visibilityOf(driver.findElement(
						By.xpath(String.format("//input[@name = '%s']", "btnK")))));																																			// ?
		element.click();
		element = wait.until(ExpectedConditions
				.visibilityOf(driver.findElement(By.id("resultStats"))));
		assertThat(element, notNullValue());
		assertTrue(element.getText().matches("^.*\\b(?:\\d+)\\b.*$"));
		driver.close();
		driver.quit();


ощибка была в использовании переменных класса а не метод-scope.

проект положен в
https://github.com/s...elenium-fluxbox
директория  https://github.com/s.../master/example


  • 1

#9 Alemix

Alemix

    Новый участник

  • Members
  • Pip
  • 34 сообщений
  • ФИО:Герасимов Алексей Михайлович

Отправлено 17 января 2019 - 04:25

Спасибо. Ну, может быть, кому-нибудь будет полезно ))


  • 0

#10 the0

the0

    Новый участник

  • Members
  • Pip
  • 47 сообщений
  • ФИО:Сергей


Отправлено 07 февраля 2019 - 12:26

Я использую такой подход:
Отдельный класс, реализующий фабрику драйверов.
TestNG создает поток в @Before и затем я ищу "живой" драйвер используя фабрику в данном потоке. Если драйвера в потоке нет, создаю новый. Второй, третий и т.п. тесты/классы/сюты (в зависимости от ваших целей) будут получать новый инстанс драйвера для своего потока и работать в новом браузере. Сама переменная драйвера каждый раз укладывается в контейнер ThreadLocal и перед driver.quit извлекается из него же с тем, чтобы мы не "убили" случайно драйвер из соседнего потока.

Далее в конфиге хмл можно указать нужное количество потоков переменной thead-count. Ну, а сам TestNG может параллелить на том уровне, на котором вам нужно: методы/тесты/классы/сьюты (параметер parallel). По умолчанию количество потоков, если не ошибаюсь, равняется пяти.

Так вам не придется использовать @DataProvider, каждый браузер будет управляться своим драйвером, а параллельность будет происходить средствами самого TestNG и управляться из xml конфига. Получается гибко и удобно, особенно в случае, где в определенных сьютах вам не нужно запускать тесты параллельно (например они работают с одной и той же сущностью в приложении), а в других - необходимо.


  • 0

Основательный подход


#11 Spock

Spock

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 772 сообщений
  • ФИО:Роман

Отправлено 07 февраля 2019 - 12:44

 

Я использую такой подход:

Отдельный класс, реализующий фабрику драйверов.
TestNG создает поток в @Before и затем я ищу "живой" драйвер используя фабрику в данном потоке. Если драйвера в потоке нет, создаю новый. Второй, третий и т.п. тесты/классы/сюты (в зависимости от ваших целей) будут получать новый инстанс драйвера для своего потока и работать в новом браузере. Сама переменная драйвера каждый раз укладывается в контейнер ThreadLocal и перед driver.quit извлекается из него же с тем, чтобы мы не "убили" случайно драйвер из соседнего потока.

Далее в конфиге хмл можно указать нужное количество потоков переменной thead-count. Ну, а сам TestNG может параллелить на том уровне, на котором вам нужно: методы/тесты/классы/сьюты (параметер parallel). По умолчанию количество потоков, если не ошибаюсь, равняется пяти.

Так вам не придется использовать @DataProvider, а параллельность будет происходить средствами самого TestNG и управляться из xml конфига. Получается гибко и удобно, особенно в случае, где в определенных сьютах вам не нужно запускать тесты параллельно (например они работают с одной и той же сущностью в приложении), а в других - необходимо.

да, такой подход к параллелизации был актуален до прихода контейнеризации


  • 0

#12 the0

the0

    Новый участник

  • Members
  • Pip
  • 47 сообщений
  • ФИО:Сергей


Отправлено 07 февраля 2019 - 12:53

 

 

Я использую такой подход:

Отдельный класс, реализующий фабрику драйверов.
TestNG создает поток в @Before и затем я ищу "живой" драйвер используя фабрику в данном потоке. Если драйвера в потоке нет, создаю новый. Второй, третий и т.п. тесты/классы/сюты (в зависимости от ваших целей) будут получать новый инстанс драйвера для своего потока и работать в новом браузере. Сама переменная драйвера каждый раз укладывается в контейнер ThreadLocal и перед driver.quit извлекается из него же с тем, чтобы мы не "убили" случайно драйвер из соседнего потока.

Далее в конфиге хмл можно указать нужное количество потоков переменной thead-count. Ну, а сам TestNG может параллелить на том уровне, на котором вам нужно: методы/тесты/классы/сьюты (параметер parallel). По умолчанию количество потоков, если не ошибаюсь, равняется пяти.

Так вам не придется использовать @DataProvider, а параллельность будет происходить средствами самого TestNG и управляться из xml конфига. Получается гибко и удобно, особенно в случае, где в определенных сьютах вам не нужно запускать тесты параллельно (например они работают с одной и той же сущностью в приложении), а в других - необходимо.

да, такой подход к параллелизации был актуален до прихода контейнеризации

 

О какой именно инфраструктуре вы говорите? И в чем будет различие при использовании контейнеров?


  • 0

Основательный подход


#13 Spock

Spock

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 772 сообщений
  • ФИО:Роман

Отправлено 07 февраля 2019 - 13:01

 

 

О какой именно инфраструктуре вы говорите? И в чем будет различие при использовании контейнеров?

каждый инстанс драйвера с браузером в своём контейнере. Так архитектура будет надёжная - они не мешают друг другу как при запуске в одной ОС - один браузер может подвиснуть забрав 100% цпу, другой отъест память, третий закрэшится, и они помешают выполниться остальным тестам. Так же архитектура будет sclalable и portable - легко добавлять/убирать ресурсы, запускать на разных машинах и в облаке, запускать на любых ОС. Так же контейнеры faltproof, можно их легко перезапускать при фейле


  • 0

#14 the0

the0

    Новый участник

  • Members
  • Pip
  • 47 сообщений
  • ФИО:Сергей


Отправлено 07 февраля 2019 - 13:10

каждый инстанс драйвера с браузером в своём контейнере. Так архитектура будет надёжная - они не мешают друг другу как при запуске в одной ОС - один браузер может подвиснуть забрав 100% цпу, другой отъест память, третий закрэшится, и они помешают выполниться остальным тестам. Так же архитектура будет sclalable и portable - легко добавлять/убирать ресурсы, запускать на разных машинах и в облаке, запускать на любых ОС. Так же контейнеры faltproof, можно их легко перезапускать при фейле

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


  • 0

Основательный подход


#15 the0

the0

    Новый участник

  • Members
  • Pip
  • 47 сообщений
  • ФИО:Сергей


Отправлено 07 февраля 2019 - 13:38

каждый инстанс драйвера с браузером в своём контейнере. Так архитектура будет надёжная - они не мешают друг другу как при запуске в одной ОС - один браузер может подвиснуть забрав 100% цпу, другой отъест память, третий закрэшится, и они помешают выполниться остальным тестам. Так же архитектура будет sclalable и portable - легко добавлять/убирать ресурсы, запускать на разных машинах и в облаке, запускать на любых ОС. Так же контейнеры faltproof, можно их легко перезапускать при фейле

Параллельность достигается на уровне кода, там где "живут" инстансы драйвера. Код работает на машине отдельно от браузеров и никак не связан с инфраструктурой, он о ней попросту не знает ничего. Наживую браузеры бегают или в контейнерах. После того, как мы запросили сессию по URL хаба для RemoteDriver, ничего дальше не параллелится. Может вы имели ввиду, что очереди ваших запросов могут распределяться каким-либо балансером, типа ggr? Но это не имеет отношения к параллельности самих тестов и к тому, как это реализовано на уровне кода.


  • 1

Основательный подход




Темы с аналогичным тегами Selenium, JUnit

Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных