Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Запуск maven тестов с использованием профилей


(Diana) #1

у меня запускаются тесты командой mvn test в командной строке

хочу настроить джобы в Jenkins, чтобы тесты выполнялись в разных браузерах, например, chrome и firefox

для этого я изменила немного профили в pom.xml:

<profile>
      <id>chrome</id>
      <properties>
        <env>local</env>
        <user.username></user.username>
        <user.password></user.password>
        <grid2.hub></grid2.hub>
        <site.url>http://mysite.com</site.url>
        <browser.name>chrome</browser.name>
        <browser.version></browser.version>
        <browser.platform></browser.platform>
      </properties>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
    </profile>
    <profile>

пробую запустить следующей командой

mvn test -P chrome

но все равно стартует Firefox и тесты выполняются в нем


(Sergey Korol) #2

Недостаточно информации, чтобы дать ответ. Тут возникает сразу ряд вопросов:

  1. Какой фреймворк используете: самописный или оупен сорс?
  2. Каким был рабочий оригинал пома?
  3. Используете JUnit или TestNG?
  4. Каков код создания драйвера, где вы сетите нужный браузер?

(Diana) #3

тут есть вопросы на которые я не могу ответить (
я только осваиваю инструменты
я расскажу как делала, может это прояснит )

  1. сделала архетип для проекта отсюда
    https://github.com/barancev/webdriver-java-quickstart-archetype
  2. импотртировала проект в Eclipse
  3. создала несколько тестов на пробу и забросила их в папку src/test/java/название пакета
  4. единственное, там был TestBase.java, он сложный какой-то, не смогла разобраться, поэтому создала свой CommonClass.java, где находятся Before/After Method
@BeforeMethod
public void setUp() throws Exception {
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
	  }
@AfterMethod
public void tearDown() throws Exception {
driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
fail(verificationErrorString);
    }
 }
  1. тесты запускаются mvn test

но не запускаются с параметром профиля почему-то, хотя pom.xml запускается отдельно из Eclipse и ошибок нет, но вот стартует только Firefox


(Diana) #4

В общем методом проб и ошибок я поняла, что не надо было мне менять TestBase.java на свой.

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

Если вам не сложно, подскажите как настроить эти Before/After, чтобы каждый тест запускался в браузере и по завершении брайзер делал quit , потом второй старт и выход и тд.

Вот методы, которые были в шаблоне

public class TestBase {
	private static final String SCREENSHOT_FOLDER = "target/screenshots/";
	private static final String SCREENSHOT_FORMAT = ".png";

	protected WebDriver driver;

	protected String gridHubUrl;

	protected String baseUrl;

	protected Browser browser;

	@BeforeClass
	public void init() {
		baseUrl = PropertyLoader.loadProperty("site.url");
		gridHubUrl = PropertyLoader.loadProperty("grid2.hub");

		browser = new Browser();
		browser.setName(PropertyLoader.loadProperty("browser.name"));
		browser.setVersion(PropertyLoader.loadProperty("browser.version"));
		browser.setPlatform(PropertyLoader.loadProperty("browser.platform"));

		String username = PropertyLoader.loadProperty("user.username");
		String password = PropertyLoader.loadProperty("user.password");
		
		driver = WebDriverFactory.getInstance(gridHubUrl, browser, username,
				password);
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
	}

	@AfterSuite(alwaysRun = true)
	public void tearDown() {
		if (driver != null) {
			driver.quit();
		}
	}

тут сделано BeforeClass и AfterSuite

простая замена, например, Before/After Method или Before/After Test ничего не дала, выполняется всегда только первый тест, разобраться сама не могу, мозгов не хватает


(Sergey Korol) #5

Бегло глянув код, увидел следующее:

  1. TestBase дергает фабрику, чтобы создать экземпляр драйвера.
  2. Конфигурация браузера подтягивается из проперти файлов, которые ссылаются на мейвен профили.

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

В вашем же коде, которым вы заменили исходный, всегда используется FirefoxDriver. Откуда ж тут хрому взяться? Если уж используете свой собственный инициализатор, то позаботьтесь о логике выбора драйвера в зависимости от того, что указано в профиле. Но я бы не рекомендовал изобретать велосипед, если пока еще не до конца понимаете принцип работы драйвера. Разберитесь в готовом коде, он как раз адаптирован под профили. И никто не мешает вам init и tearDown использовать с BeforeMethod / AfterMethod.


(Sergey Korol) #6

Возможно проблема в TestNG конфиг файле. Покажите класс тестов и ваш конфиг.

В исходниках тестов использовалась аннотация BeforeClass. Т.е. пейдж обджект инициализируется 1 раз для всех тестов класса. Тут тоже может быть проблема при изменении аннотаций в init / tearDown.

Еще советую почитать об иерархии аннотаций в TestNG, а также основах создания конфиг файлов.


(Diana) #7

вернула TestBase.java на место, теперь тесты extends на него

классы

конфиг TestNG

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Tests" verbose="5" data-provider-thread-count="1">
	<test name="Test1">
		<parameter name="path" value="/"/>
		<classes>
		        <class name="ru.st.selenium.pages.TestBase"/>
     			<class name="ru.st.selenium.pages.AddEquipment"/>
      			<class name="ru.st.selenium.pages.AddBuilding"/>
			    <class name="ru.st.selenium.pages.GenerateData"/>
		</classes>
	</test>  
</suite>

(Sergey Korol) #8

Ну, во-первых, TestBase не должен присутствовать в конфиге. Во-вторых, пока еще не ясно, как вы манипулируете аннотациями внутри тестовых классов. Если вы хотите, чтобы браузер стартовал перед каждым тестом, то init / tearDown / testInit должны содержать BeforeMethod/AfterMethod аннотации.


(Александр Таранков) #9

Либо можно сделать проще (на мой взгляд):

  1. Оставить свой CommonClass с уже работающими BeforeMethod/AfterMethod
  2. Взять метод init() (вместе с аннотацией @BeforeClass) из TestBase, скопировать к себе в класс и оставить в нём чтение пропертей, в проперти класса
  3. Инициализацию браузера и драйвера перенести в свой метод setUp, чтобы она делалась перед каждым тестом

Ничего волшебного TestBase не делает, просто читает проперти из конфига, а в твоем CommonClass этого не делается, поэтому и запускается всегда только Firefox


(Diana) #10

мне надо как можно проще, поэтому сделала как вы советовали,

  1. перенесла init() со всеми Property в CommonClass

только не смогла перенести:

String username = PropertyLoader.loadProperty("user.username");
String password = PropertyLoader.loadProperty("user.password");

потому что username и password выдают ошибку в данной строке в методе setUp()

driver = WebDriverFactory.getInstance(gridHubUrl, browser, username, password);
  1. перенесла в setUp() инициализацию браузера и драйвера
browser = new Browser();
String username = PropertyLoader.loadProperty("user.username");
String password = PropertyLoader.loadProperty("user.password");
driver = WebDriverFactory.getInstance(gridHubUrl, browser, username, password);

вот что получилось в итоге:

public class CommonClass {

	protected WebDriver driver;
	protected String baseUrl;
	protected Browser browser;
	protected String gridHubUrl;
	
@BeforeClass
public void init() {
baseUrl = PropertyLoader.loadProperty("site.url");
gridHubUrl = PropertyLoader.loadProperty("grid2.hub");
browser.setName(PropertyLoader.loadProperty("browser.name"));
browser.setVersion(PropertyLoader.loadProperty("browser.version"));
browser.setPlatform(PropertyLoader.loadProperty("browser.platform"));
}

@BeforeMethod
public void setUp() throws Exception {
String username = PropertyLoader.loadProperty("user.username");
String password = PropertyLoader.loadProperty("user.password");
browser = new Browser();
driver = WebDriverFactory.getInstance(gridHubUrl, browser, username, password);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
}

@AterMethod
public void tearDown() throws Exception {
driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
fail(verificationErrorString);
}
}

но при попытке запустить правой кнопкой пакет выдает ошибку:

FAILED CONFIGURATION: @BeforeClass init

please, help


(Jane Tymoschuk) #11

если учитывать, что BeforeClass будет выполняться первым, тут вообще должен быть nullpointer, не вижу, чтобы browser где-то инициализировался
он объъявлен, но экземпляр не создан. при первой же попытке сделать browser.setName, он будет валиться

browser = new Browser(); должен быть до setName, а не в Before Metod в таком случае… либо setName и остальное в BeforeMethod


(Sergey Korol) #12
  1. Вы в BeforeClass используете неинициализированный объект browser.
  2. Глядя в код фабрики, username / password вам не понадобятся в большинстве случаях, так что можете и 2 null передать в качестве параметров.
  3. Чтобы BeforeClass не фейлился, перенесите инициализацию браузера в BeforeClass перед setName, как уже сказали выше.

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


(Diana) #13

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

перенесла инициализацию объекта browser

@BeforeClass
public void init() {
baseUrl = PropertyLoader.loadProperty("site.url");
gridHubUrl = PropertyLoader.loadProperty("grid2.hub");
browser = new Browser();
browser.setName(PropertyLoader.loadProperty("browser.name"));
browser.setVersion(PropertyLoader.loadProperty("browser.version"));
browser.setPlatform(PropertyLoader.loadProperty("browser.platform"));
String username = PropertyLoader.loadProperty("user.username");
String password = PropertyLoader.loadProperty("user.password");
}

первые тест выполняется, на втором ошибка

Session ID is null. Using WebDriver after calling quit()?


(Sergey Korol) #14

Ваш второй тест пытается использовать экземпляр драйвера, который уже убит, что является странным, ибо инициализация идет в BeforeMethod. Покажите код тестового класса, где 1 тест запускается, а второй - нет.


(Sergey Korol) #15

А, стоп… Смотрю в код: драйвер статический. Если url хаба не задан, мы идем в перегруженный getInstance, который проверяет driver на null. И если != null, то возвращает существующий инстанс. Говоря простым языком, делая quit(), вы закрываете сессию, но сам объект driver’a все еще существует на уровне класса, а не экземпляра, ибо он объявлен как static. В качестве quick fix, можете попробовать дописать driver = null; после quit(). Должно сработать. Хотя, я бы вообще убрал статику, если вы используете наследование, дабы не вносить лишней путаницы. К тому же, со статикой у вас будут возникать проблемы при масштабировании, если не добавить спец. джава контейнер.


(Diana) #16

два моих тестовых класса и метод login()

public class AddEquipment extends CommonClass {
@org.testng.annotations.Test
public void testEquipmentCreate() throws Exception {
login();
logout();
	  }
	}
	
public class AddBuilding extends CommonClass {
@Test
public void testAddBuilding() throws Exception { 
login();
logout();
	  }
	}

protected void login() throws InterruptedException {
driver.get("http://mysite.com/");
driver.findElement(By.xpath("//div [@id=\"login_form\"]//input[@placeholder=\"пользователь\"]")).clear();
driver.findElement(By.xpath("//div [@id=\"login_form\"]//input[@placeholder=\"пользователь\"]")).sendKeys("dianam");
driver.findElement(By.xpath("//div [@id=\"login_form\"]//input[@placeholder=\"пароль\"]")).clear();
driver.findElement(By.xpath("//div [@id=\"login_form\"]//input[@placeholder=\"пароль\"]")).sendKeys("123456");
driver.findElement(By.xpath("//span/button")).click();

(Sergey Korol) #17

Смотрите ответ выше. Проблема не в тестах.


(Diana) #18

попробовала дописать, нет, та же ошибка (

FAILED CONFIGURATION: @BeforeMethod setUp
Session ID is null. Using WebDriver after calling quit()?


(Sergey Korol) #19

Хм, ну да, все правильно. Вы ведь манипулируете нестатическим инстансом в тестах, но в самой фабрике он по-прежнему висит, как static.

Как насчет убрать:

if (webDriver != null) {
return webDriver;
}

из getInstance? Хотя, все это workarounds. Использование mix static + non static driver ни к чему хорошему обычно не приводит.


(Александр Таранков) #20

Подскажи где ты код смотришь?