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

Фотография

JUnit+Selenium Grid+Распараллеливание тестов

JUnit Selenium Grid

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

#1 Yago

Yago

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

  • Members
  • Pip
  • 7 сообщений
  • Город:Тольятти

Отправлено 18 июня 2015 - 07:41

Доброе время суток!

Коллеги, столкнулся с вопросом, который не могу решить самостоятельно.

Имеем:
- развернутый и настроенный Selenium Grid hub
- развернутые и настроенные Selenium Grid nodes (2 шт)
- автотест, написанный в JUnit

Действия:
- стартуем hub
- стартуем nodes
- в Eclipse запускаем автотест

Ожидаемыый результат:
- автотест должен выполняться на двух настроенных nodes одновременно

Текущий результат:
- автотест выполняется только на одной из nodes

Чтение сопутствующих материалов подселило мысль, что распараллеливает выполнение тестов не Selenium Grid, а framework (в нашем случае JUnit) - это верно?

Подскажите пожалуйста (дайте ссылку) как настроить JUnit на параллельное выполнение тестов? (Переезд в TestNG по объективным проектным причинам не возможен).

 

Спасибо всем откликнувшемся! :-)


  • 0

#2 BabyRoot

BabyRoot

    Специалист

  • Members
  • PipPipPipPipPip
  • 833 сообщений


Отправлено 18 июня 2015 - 08:14

Верно, надо параллелить на уровне юнита - http://yandex.ru/sea...ть JUnit&lr=213

Первая ссылка - http://internetka.in...tests-parallel/


  • 0

#3 Yago

Yago

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

  • Members
  • Pip
  • 7 сообщений
  • Город:Тольятти

Отправлено 18 июня 2015 - 09:48

Верно, надо параллелить на уровне юнита - http://yandex.ru/sea...ть JUnit&lr=213

Первая ссылка - http://internetka.in...tests-parallel/

BabyRoot, спасибо за ссылку.

В руководстве написано:

"Начиная с версии 4.7 в JUnit была добавлена возможность параллельного запуска, для этого нужно настроить Maven следующим образом:..."

 

Дело в том, что для запуска автотестов мы не используем Maven (такая практика отсутствует).


  • 0

#4 checo

checo

    Опытный участник

  • Members
  • PipPipPipPip
  • 400 сообщений
  • Город:Н.Новгород

Отправлено 18 июня 2015 - 09:59


Дело в том, что для запуска автотестов мы не используем Maven (такая практика отсутствует).

 

 

А какая присутствует?

 

Если запускать тесты кнопкой из IDE, они запустятся в 1 поток. Для параллельного запуска нужен или независимый запуск потоков из командной строки, или средства билд инструмента, будь то Maven или что-то еще.

Для Ant тоже есть практика, например: http://blog.code-cop...llel-junit.html


  • 0

#5 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 18 июня 2015 - 10:00

Дело в том, что для запуска автотестов мы не используем Maven (такая практика отсутствует).

 

 

Так а что вы используете ? ant или градл


  • 0

#6 Yago

Yago

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

  • Members
  • Pip
  • 7 сообщений
  • Город:Тольятти

Отправлено 18 июня 2015 - 10:03

 


Дело в том, что для запуска автотестов мы не используем Maven (такая практика отсутствует).

 

 

А какая присутствует?

 

Если запускать тесты кнопкой из IDE, они запустятся в 1 поток. Для параллельного запуска нужен или независимый запуск потоков из командной строки, или средства билд инструмента, будь то Maven или что-то еще.

Для Ant тоже есть практика, например: http://blog.code-cop...llel-junit.html

 

Тесты запускаются либо из IDE (Eclipse) либо из командной строки.

 

Подскажите пожалуйста, как можно запустить паралельные тесты из командной строки?


  • 0

#7 barancev

barancev

    Администратор

  • Admin
  • PipPipPipPipPipPip
  • 6 872 сообщений
  • ФИО:Алексей Баранцев
  • Город:Россия, Москва


Отправлено 19 июня 2015 - 07:31

Давайте вернёмся к исходной точке.

Я обратил внимание, что Вы изначально ожидаете от Selenium Grid того, что он делать не умеет, не предназначен для этого:

 

Ожидаемыый результат:

- автотест должен выполняться на двух настроенных nodes одновременно

 

Selenium Grid -- это "балансировщик нагрузки". Он предназначен не для "дублирования", а для распределения браузеров по узлам. То есть, если у вас есть грид с двумя нодами, и если вы в тестах открываете два браузера (инициализируете два драйвера) -- они будут созданы на разных нодах.

 

Используется это как правило для ускорения выполнения тестов. То есть, например, если у вас есть 1000 тестов, то выполняя их при помощи грида с двумя нодами вы сможете их выполнить в два раза быстрее, чем если выполнять всё в одном браузере.

 

Да, для этого вам всё равно придётся научиться запускать тесты в параллельных потоках, этот вопрос остаётся открытым. Я просто уточнил назначение грида.


  • 0
Алексей Баранцев
Тренинги для тестировщиков (тестирование производительности, защищенности, тест-дизайн, автоматизация):
Линейка тренингов по Selenium

#8 Yago

Yago

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

  • Members
  • Pip
  • 7 сообщений
  • Город:Тольятти

Отправлено 19 июня 2015 - 09:21

Давайте вернёмся к исходной точке.

Я обратил внимание, что Вы изначально ожидаете от Selenium Grid того, что он делать не умеет, не предназначен для этого:

 

Ожидаемыый результат:

- автотест должен выполняться на двух настроенных nodes одновременно

 

Selenium Grid -- это "балансировщик нагрузки". Он предназначен не для "дублирования", а для распределения браузеров по узлам. То есть, если у вас есть грид с двумя нодами, и если вы в тестах открываете два браузера (инициализируете два драйвера) -- они будут созданы на разных нодах.

 

Используется это как правило для ускорения выполнения тестов. То есть, например, если у вас есть 1000 тестов, то выполняя их при помощи грида с двумя нодами вы сможете их выполнить в два раза быстрее, чем если выполнять всё в одном браузере.

 

Да, для этого вам всё равно придётся научиться запускать тесты в параллельных потоках, этот вопрос остаётся открытым. Я просто уточнил назначение грида.

Алексей, спасибо за уточнение.

 

Решили проблему параллелизации переходом на TestNG.

 

Вот пример части кода работающей конфигурации:

 

@BeforeMethod
    public void setUp() throws MalformedURLException{
        
        DesiredCapabilities capability = new DesiredCapabilities();
        capability.setBrowserName("firefox");    
        capability.setPlatform(Platform.ANY);
        driver = new RemoteWebDriver(new URL("http://192.168.98.78:4444/wd/hub"), capability);


        
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        driver.manage().window().maximize();
        driver.get("http://somehost:8180/platform");       
        
    }

    @Test(singleThreaded = false,threadPoolSize=6 , invocationCount=6)
    public void openLoginPage(){

 

Спасибо всем откликнувшемся и сочувствующим! :-)


  • 0

#9 Yago

Yago

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

  • Members
  • Pip
  • 7 сообщений
  • Город:Тольятти

Отправлено 19 июня 2015 - 09:26

Плюс, в догонку к предыдущему сообщению ссылка на manual по настройке selenium grid: https://www.packtpub...lenium_Grid.pdf (начинающим (таким как я) читать обязательно!)


  • 0

#10 Opra

Opra

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

  • Members
  • Pip
  • 3 сообщений
  • ФИО:Яковенко Оксана
  • Город:Киев-Днепропетровск

Отправлено 04 декабря 2015 - 11:18

У меня тема та же, пожалуйста, давайте продолжим!!!)))

Уже которую неделю бьюсь с этой 'распараллельностью'....Скоро мозги взорвутся.

На TestNG принципиально не хочу переходить, хочу добиться этого с любимым и привычным JUnit.

 

У меня пока есть около 200 тестов, они проходятся на Firefox, последовательно)) 

Ранятся они с помощью maven test. Это занимает много  времени, и моя цель- распараллелить тесты, чтоб сократить время прохождения автотестов 

 

Итак, имею:

- Тесты написаны на Java +Selenium WebDriver+Page Object pattern. 

   Каждый класс с тестами наследуется от базового, по типу:

 

public class TestBaseSetup {

protected static WebDriver driver;
 
@BeforeClass
   public static void setUp() {
       URL host = null;
       DesiredCapabilities capabilities = new DesiredCapabilities();
       capabilities.setBrowserName("firefox");
       capabilities.setPlatform(Platform.ANY);;
       try {
          host = new URL("http://localhost:4444/grid/register");
       } catch (MalformedURLException e) {
          e.printStackTrace();
       }
     driver = new RemoteWebDriver(host, capabilities);
     driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
     driver.manage().window().maximize();
     driver.get("http://my site/my page");
}
 
@AfterClass
   public static void tearDown() {
     driver.quit();
   }
}
 
public class AddNewTest extends TestBaseSetup {
private ContractsPageSteps contractPS = new ContractsPageSteps(driver);
private ContractCommonSteps contractS = new ContractCommonSteps(driver);
private LoginPageSteps loginP = new LoginPageSteps(driver);
 
private String client = "TRNTY";
 
@Test
public void addNewContract() {
    loginP.loginAs("user", "123");
    contractS.createNewContract(client);
    assertTrue(contractPS.isContractFound(client));
}
}
 
- Стартую selenium Grid hub :
    java -jar selenium-server-standalone-2.48.2.jar -role hub
- Стартую нод с Firefox 
java -jar selenium-server-standalone-2.48.2.jar -role node -hub http://localhost:4444/grid/register -port 5557 -browser browserName=firefox,version=42.0,maxInstances=5
 Как я полагаю,именно параметр  'maxInstances=5' нужен для того , чтоб на одном ноде запустились 5 инстансов FF, и тесты смогли распарралелиться.
 
- дальше конфигурю pom.xml для maven-surefire-plugin:
 <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.18.1</version>
            <configuration>
                 <parallel>classes</parallel>
                <threadCount>2</threadCount>
          </configuration>
В мавен документации сказано, что можно еще настроить эти параметры, нужны ли они мне в данном случае , я не до конца понимаю..  
                 <reuseForks>false</reuseForks>
                 <forkCount>2.5C</forkCount>
                 <testFailureIgnore>true</testFailureIgnore>
 
 
ВСЕ!
Запускаю
  mvn clean test
Выпадает ошибка:
 
 
 
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running cms.Items.Training.AddNewTest
Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 0.001 sec <<< FA
ILURE! - in cms.Items.Training.AddNewTest
cms.Items.Training.AddNewTest  Time elapsed: 0.001 sec  <<< ERROR!
org.openqa.selenium.WebDriverException: <html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 500 </title>
</head>
<body>
<h2>HTTP ERROR: 500</h2>
<p>Problem accessing /grid/register/session. Reason:
<pre>    java.lang.NullPointerException</pre></p>
<hr /><i><small>Powered by Jetty://</small></i>
</body>
</html>
Command duration or timeout: 855 milliseconds
Build info: version: '2.48.2', revision: '41bccdd10cf2c0560f637404c2d96164b67d9d
67', time: '2015-10-09 13:08:06'
System info: host: 'IOIakovenko', ip: '10.98.3.107', os.name: 'Windows 8', os.ar
ch: 'amd64', os.version: '6.2', java.version: '1.8.0_20'
Driver info: org.openqa.selenium.remote.RemoteWebDriver
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstruct
orAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingC
onstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
        at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.
java:206)
        at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHa
ndler.java:158)
        at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.ja
va:647)
        at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriv
er.java:247)
        at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.jav
a:129)
        at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.jav
a:156)
        at oiak.work.TestBaseSetup.setUp(TestBaseSetup.java:37)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(Framework
Method.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCal
lable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMe
thod.java:47)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.
java:24)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.ja
va:27)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:27)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.apache.maven.surefire.junitcore.pc.Scheduler$1.run(Scheduler.java
:387)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:51
1)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.
java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor
.java:617)
        at java.lang.Thread.run(Thread.java:745)

 

Я уже не знаю что делать... 

 

Помогите, пожалуйста!!)))) 


  • 0

#11 checo

checo

    Опытный участник

  • Members
  • PipPipPipPip
  • 400 сообщений
  • Город:Н.Новгород

Отправлено 04 декабря 2015 - 17:51

Для начала, http://localhost:4444/grid/register - это пишется в командной строке нода, чтоб он зарегистрировался на хабе.

А в тестах подключемся к http://localhost:4444/wd/hub

 

Потом, посмотрите этот ответ насчет статических членов класса. Поле WebDriver лучше не делать статическим, а создавать заново в @BeforeClass, либо иметь отдельный класс-провайдер инстансов WebDriver, который будет их кешировать в привязке к номеру треда.


  • 0

#12 Opra

Opra

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

  • Members
  • Pip
  • 3 сообщений
  • ФИО:Яковенко Оксана
  • Город:Киев-Днепропетровск

Отправлено 07 декабря 2015 - 10:10

Для начала, http://localhost:4444/grid/register - это пишется в командной строке нода, чтоб он зарегистрировался на хабе.

А в тестах подключемся к http://localhost:4444/wd/hub

 

Потом, посмотрите этот ответ насчет статических членов класса. Поле WebDriver лучше не делать статическим, а создавать заново в @BeforeClass, либо иметь отдельный класс-провайдер инстансов WebDriver, который будет их кешировать в привязке к номеру треда.

По первому пункту исправила, спасибо.

 

По второму -  как я не крутила- вертела, не смогла отделаться от данного решения( когда драйвер статик поле) ,  т к Junit требует статичности в аннотируемом методе @BeforeClass!!!

Может есть какой-то ресурс, где есть более подробное описание

 

Читала про решения, когда предлагают перейти на TestNG....Но я пробую добиться это с помощью Junit...


  • 0

#13 checo

checo

    Опытный участник

  • Members
  • PipPipPipPip
  • 400 сообщений
  • Город:Н.Новгород

Отправлено 07 декабря 2015 - 11:04

Ну, если с этим не будет проблем, можно попробовать и так. Именно таким образом запускать не пробовал.

Просто на нашем проекте мы сталкивались с конфликтом между статическими полями, но запускали через другой инструмент.

 

На всякий случай, если понадобится убрать статику, надо просто перенести в @Before и делать проверку на null. Если null, тогда инициализируем, и это произойдет только перед первым тестом.


  • 0

#14 barancev

barancev

    Администратор

  • Admin
  • PipPipPipPipPipPip
  • 6 872 сообщений
  • ФИО:Алексей Баранцев
  • Город:Россия, Москва


Отправлено 07 декабря 2015 - 11:40

Чтобы избавиться от static -- используйте @Before.

А чтобы браузер при этом не перезапускался постоянно -- используйте фабрику: http://selenium2.ru/...verfactory.html


  • 0
Алексей Баранцев
Тренинги для тестировщиков (тестирование производительности, защищенности, тест-дизайн, автоматизация):
Линейка тренингов по Selenium

#15 Opra

Opra

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

  • Members
  • Pip
  • 3 сообщений
  • ФИО:Яковенко Оксана
  • Город:Киев-Днепропетровск

Отправлено 07 декабря 2015 - 13:46

Дело в том, что если в базовом классе TestBaseSetup я и смогу заменить  @BeforeClass на  @Before то тогда конфликт возникнет в самих классах с тестами, т к там я периодически использую @BeforeClass (например  до выполнения тестов, я создаю некую сущность, и потом ее тестирую) Если и тут я изменю на @Before, то эта сущность будет создаваться перед каждым тестом... а это лишнее...

 

public class DesignTest extends TestBaseSetup {

private static ThirdPartySoftPageSteps tpP;
private static MainPageSteps mainP;
 
@BeforeClass
public static void before() {
mainP = new MainPageSteps(driver); //  тут то и требуется, чтоб драйвер  был  статичным
tpP = new ThirdPartySoftPageSteps(driver);
 
mainP.loginAs("user", "123")
          .goToProductSetup().goToThirdPartySoftwr();
tpP.createNewItem("ItemName", "60", "AApp", "Description")
}
 
 
@Test
public void test1() {
...
}
 
 
@Test
public void test2() {
...
}
.......

  • 0

#16 barancev

barancev

    Администратор

  • Admin
  • PipPipPipPipPipPip
  • 6 872 сообщений
  • ФИО:Алексей Баранцев
  • Город:Россия, Москва


Отправлено 08 декабря 2015 - 13:56

А если используете static -- тогда лучше попрощаться с параллельностью. Выбор есть :)

 

Убирайте @BeforeClass, меняйте его на @Before, и учитесь использовать ThreadLocal вместо static.


  • 0
Алексей Баранцев
Тренинги для тестировщиков (тестирование производительности, защищенности, тест-дизайн, автоматизация):
Линейка тренингов по Selenium



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

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

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