Здравствуйте.
Возникла проблема с которой я не могу пока разобраться.
Сам я занялся автоматизацией совсем недавно и очень многого еще не знаю.
У меня есть тесты на java. Запускаю я их используя IDE IntelliJ.
Процесс запуска выглядит так - я открываю файл xml с описанием <suite> <test> <class>. Перед запуском указываю параметры в конфигурации -Dproject=myproject -Dselenide.browser=chrome
Ну и поехали.
Все работает все здорово.
Сейчас я пишу свои тесты. Если я запускаю их непосредственно вызывая класс, то все норм. Если я пытаюсь использовать вышеописанный метод, то возникают проблемы...
Суть проблемы такая:
Если я в xml указываю <suite name="Main Test Suite" parallel="methods" thread-count="3" verbose="1" > и пытаюсь запустить тесты, то у меня возникает ошибка:
java.lang.IllegalStateException: No webdriver is bound to current thread: 14. You need to call open(url) first.
Если я указываю в xml <suite name="Main Test Suite" verbose="1" > то тесты проходят без ошибок.
Я так понимаю что проблема кроется где-то в xml
Гугление пока ни к чему не привело
Возможно кто-то сталкивался с подобным и может мне подсказать что я делаю не так?
Автоматизация Selenide + TestNG
#1
Отправлено 25 июня 2019 - 07:27
#2
Отправлено 25 июня 2019 - 13:16
Сложно сказать без кода, особенно - того места, где Вы браузер инициализируете.
Проблема не в xml - а в самом коде.
Вы пытаетесь запустить свои тесты в три потока, но браузер, судя по ошибке, объявляете так, что тесты его только в одном потоке видят.
#3
Отправлено 26 июня 2019 - 05:36
Вот мой класс авторизации
public class PortalAuthPage { private ReadCustomProperties portalAuthProperties = new ReadCustomProperties("src/test/resources/configs/portalAuth.properties"); private SelenideElement loginInput = $(byXpath("//input[@id='_com_****_LoginPortlet_login']")); private SelenideElement passwordInput = $(byXpath("//input[@id='_com_****_login_web_portlet_LoginPortlet_password']")); private SelenideElement loginSubmitButton = $(byXpath("//button[contains(@id,'_com_***_login_web_portlet_LoginPortlet')]")); public void auth() { open("/c/portal/login"); if (loginInput.exists()) { loginInput.setValue(portalAuthProperties.readProperty("adminUser")); passwordInput.setValue(portalAuthProperties.readProperty("adminUserPassword")); loginSubmitButton.click(); sleep(3000); } } }
Ошибка возникает на if
Т.е. страница браузер открывается и тут же падает с ексепшеном - java.lang.IllegalStateException: No webdriver is bound to current thread: 14. You need to call open(url) first.
#4
Отправлено 26 июня 2019 - 05:39
Я Selenide плохо знаю, конечно, но я не вижу в этом коде никаких намеков на инициализацию браузера. Может я просто не понимаю чего-то?
Где у Вас браузер инициализируется?
#5
Отправлено 26 июня 2019 - 06:13
Метод open
public class Selenide { public Selenide() { } public static void open(String relativeOrAbsoluteUrl) { WebDriverRunner.getSelenideDriver().open(relativeOrAbsoluteUrl); }
#6
Отправлено 26 июня 2019 - 07:53
Проблему с ексепшенном я решил... хотя пока и не понял почему так. Код
public class PortalAuthPage { private ReadCustomProperties portalAuthProperties = new ReadCustomProperties("src/test/resources/configs/portalAuth.properties"); private SelenideElement loginInput = $(byXpath("//input[@id='_com_****_LoginPortlet_login']")); private SelenideElement passwordInput = $(byXpath("//input[@id='_com_****_login_web_portlet_LoginPortlet_password']")); private SelenideElement loginSubmitButton = $(byXpath("//button[contains(@id,'_com_***_login_web_portlet_LoginPortlet')]")); public void auth() { open("/c/portal/login"); if (loginInput.exists()) { loginInput.setValue(portalAuthProperties.readProperty("adminUser")); passwordInput.setValue(portalAuthProperties.readProperty("adminUserPassword")); loginSubmitButton.click(); sleep(3000); } } }
Я переписал на
public class PortalAuthPage { private ReadCustomProperties portalAuthProperties = new ReadCustomProperties("src/test/resources/configs/portalAuth.properties"); private SelenideElement loginInput = $(byXpath("//input[@id='_com_****_LoginPortlet_login']")); private SelenideElement passwordInput = $(byXpath("//input[@id='_com_****_login_web_portlet_LoginPortlet_password']")); private SelenideElement loginSubmitButton = $(byXpath("//button[contains(@id,'_com_***_login_web_portlet_LoginPortlet')]")); public void auth() { open("/c/portal/login"); if ($(byXpath("//input[@id='_com_****_LoginPortlet_login']")).exists()) { $(byXpath("//input[@id='_com_****_LoginPortlet_login']")).setValue(portalAuthProperties.readProperty("adminUser")); $(byXpath("//input[@id='_com_****_login_web_portlet_LoginPortlet_password']")).setValue(portalAuthProperties.readProperty("adminUserPassword")); $(byXpath("//button[contains(@id,'_com_***_login_web_portlet_LoginPortlet')]")).click(); sleep(3000); } } }
Как видите, я просто вместо переменных явно указал методы... и это помогло. Причины этого мне не ясны.
Но в любом случае, многопоточность у меня не заработала и тесты продолжают запускаться по очереди
Ниже я приложил tests.xml с помощью которого я запускаю
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="Main Test Suite" parallel="methods" thread-count="3" verbose="1" > <test name="Авторизация"> <classes> <class name="ru.****.****.*****.tests.TestTest" /> </classes> </test> </suite>
Я пытаюсь добиться того что у меня откроется несколько окон браузера и в каждом прогонится свой тест. Это у меня получилось, но запускаются они строго последовательно.
#7
Отправлено 26 июня 2019 - 08:19
Добавил в свои 4 теста такой код
long id = Thread.currentThread().getId(); System.out.println("Simple test-method One. Thread id is: " + id);
Что бы убедиться что тесты запускаются в разных тредах
Получил в консоле
Simple test-method One. Thread id is: 14 Simple test-method Two. Thread id is: 29 Simple test-method Three. Thread id is: 36 Simple test-method Four. Thread id is: 36
Как видите, в настройках у меня указано 3 потока и первые три теста запускались в трех разных тредах, а четвертый в треде третьего теста. Это доказывает и то что четвертый тест начал работать в окне третьего теста. Все круто!
Но почему они не могу стартануть вместе?
#8
Отправлено 26 июня 2019 - 08:44
Пробовал таким образом
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="Main Test Suite" parallel= "methods" thread-count="3" verbose="1" > <test name="Авторизация"> <classes> <class name="ru.***.***.***.tests.TestTest"> <methods> <include name="***"/> <include name="***"/> <include name="***"/> <include name="***"/> </methods> </class> </classes> </test> </suite>
Разницы нет
#9
Отправлено 26 июня 2019 - 10:08
Проблему с xPath решил тем что перестал определять переменные в классе, а перенес определение внутрь метода.
#10
Отправлено 26 июня 2019 - 22:04
Привет!
Что на самом деле важно - это как вы в тесте объявляете переменную типа PortalAuthPage.
Скорее всего вы объявляете её как поле в классе теста.
А TestNG (и этим он хуже JUnit'а) создаёт только один инстанс теста, поэтому к следующему методу он уже устаревает. Подробнее об этом здесь: https://ru.selenide....selenide-5.0.0/
Если вы будете инициализировать переменную PortalAuthPage в методе типа @BeforeMethod, проблема решится.
P.S. А ещё лучше - переходите с TestNG на JUnit. Там с этим делом всё хорошо.
P.P.S. Про многопоточный запуск тестов: https://www.youtube....h?v=LuLBL-DHTAQ
#11
Отправлено 27 июня 2019 - 02:46
Привет!
Что на самом деле важно - это как вы в тесте объявляете переменную типа PortalAuthPage.
Скорее всего вы объявляете её как поле в классе теста.
А TestNG (и этим он хуже JUnit'а) создаёт только один инстанс теста, поэтому к следующему методу он уже устаревает. Подробнее об этом здесь: https://ru.selenide....selenide-5.0.0/
Если вы будете инициализировать переменную PortalAuthPage в методе типа @BeforeMethod, проблема решится.
P.S. А ещё лучше - переходите с TestNG на JUnit. Там с этим делом всё хорошо.
P.P.S. Про многопоточный запуск тестов: https://www.youtube....h?v=LuLBL-DHTAQ
Я как раз таки инициализирую её как метод @BeforeMethod
#12
Отправлено 27 июня 2019 - 04:01
По итогу я решил свою задачу.
На случай если кому-то пригодится:
В tests.xml указал для каждого тестового метода класса свой тег <test> </test>, а в теге <suite> </suite> указал parallel= "tests" при такой конфигурации у меня получилось запускать несколько окон браузера одновременно
Плюсы такого решения - в каждом теге <test> </test> я смог указывать свои параметры, благодаря чему я еще использовал разные браузеры что позволило проверить как веб-интерфейс работает на разных браузерах.
Минусы - 1. Не совсем понял такое поведение, parallel с указанием classes или method не запускают несколько окон, а продолжают запускать их по очереди. 2. tests.xml получается очень громоздкий
Количество пользователей, читающих эту тему: 0
0 пользователей, 0 гостей, 0 анонимных