В автоматизации совсем недавно.Пользуюсь webdriver + testng + java.
Суть проблемы: после прохождения первого тестового класса тесты падают.Отдельно запуск каждого класса проходит успешно.
Есть особенности поведения: если запускать через run as на проекте, то фейлятся оба класса, если запускаю с помощью файла testng.xml то только второй класс фейлится. Единственный вариант при котором тесты не падают без дела, это использование аннотации @Before/AfterClass, но считаю не рационально тратить каждый раз столько времени на запуск браузера.
Помогите разобраться, а то гугл ничего толкового не советует:smile:
Сам тест пока занимается ерундой, но это только набросок(на него не смотрим)
Код первого класса
package iGovTests;
import org.testng.annotations.Test;
public class UploadDocumentTest extends TestBase {
@Test
public void uploadDocumentTest() throws Exception {
app.navigateTo().documentPage();
app.navigateTo().mainPage();
}
}
код второго класса
package iGovTests;
import org.testng.annotations.Test;
public class SearchDocumentTest extends TestBase {
@Test
public void searchDocument() throws Exception {
app.navigateTo().documentPage();
app.navigateTo().searchDocumentPage();
app.navigateTo().mainPage();
}
}
код класса который отвечает за запуск/остановку браузера
package iGovTests;
import java.io.File;
import java.io.FileReader;
import java.util.Properties;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import framework.ApplicationManager;
public class TestBase {
protected ApplicationManager app;
@BeforeTest
public void setUp() throws Exception {
Properties properties = new Properties();
properties.load(new FileReader(new File("application.properties")));
app = new ApplicationManager(properties);
}
@AfterTest
public void tearDown() throws Exception {
app.stop();
}
}
стек ошибки
[TestNG] Running:
C:\Users\Дмитрий\AppData\Local\Temp\testng-eclipse-1535224077\testng-customsuite.xml
FAILED: searchDocument
java.lang.NullPointerException
at iGovTests.SearchDocumentTest.searchDocument(SearchDocumentTest.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:639)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:821)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1131)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:124)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
at org.testng.TestRunner.privateRun(TestRunner.java:773)
at org.testng.TestRunner.run(TestRunner.java:623)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:357)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:352)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:310)
at org.testng.SuiteRunner.run(SuiteRunner.java:259)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1185)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1110)
at org.testng.TestNG.run(TestNG.java:1018)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
могу ошибаться, поправите если не прав. Анотации @Before\After отвечают за то то, по какой логике будет подниматься\убиваться драйвер. У меня указано @BeforeTest/AfterTest,соответственно перед тестовыми классами и после.По этому драйвер вообще не должен убиваться…Поправте если не прав.
Если пускать руками-то фелятся оба класса. Если мавеном то первый класс отрабатывает, а второй фейлится.
вот код testng.xml не смотрите что названия классов другие…у себя переделал немного для наглядности.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test verbose="2" name="Test">
<classes>
<class name="iGovTests.DocumentsTest"/>
<class name="iGovTests.DocumentsTest2"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
простите, уточню. запуск через testng.xml и maven дает один и тот же результат(первый класс проходит, второй падает)
при запуске через временный файл testng-customsuite.xml(проект-run as) падает всё
@BeforeTest: The annotated method will be run before any test method belonging to the classes inside the tag is run. друг
поменяй на беформетод посмотри что получится ?
Вы еще раз простите за глупые вопросы(только начинаю изучать автоматизацию и программирование).
с аннотацией BeforeClass конечно все будет работать, но я считаю это нерациональный подход, так как очень много времени будет занимать старт/стоп браузера каждый раз.
Вопрос: что нужно доработать в коде, что бы создавалось нужно кол-во экземпляров ApplicationManager?
Тут дело скорее в понимании основных концепций ООП и механики работы подключаемых библиотек.
На пальцах касательно ООП: у вас есть 2 тестовых класса, каждый из которых наследует TestBase, т.е. физически у вас будет 2 независимых объекта ApplicationManager при запуске.
На пальцах касательно механики работы TestNG: у вас есть xml, в котором оба класса физически являются частью “тестовой группы”:
<test verbose="2" name="Test">
Далее вы в TestBase заключаете ключевой метод, отвечающий за инициализацию объекта ApplicationManager, под аннотацию @BeforeTest. Фактически, глядя на xml, вы ставите ограничение на вызов инициализатора ApplicationManager. Другими словами, он будет вызван лишь раз - при обработке первого класса. Отсюда и вытекает вполне логичный NPE, т.к. второй объект остается неинициализированным. Вся ирония в том, что вы сами это ограничение и поставили.
Исходя из того, что вас категорически не устраивает инициализация драйвера на уровне класса, выхода тут 2:
Вынуждающий менять область видимости ApplicationManager:
protected static ApplicationManager app;
При этом, вы автоматически добавляете себе головной боли при потенциальном внедрении масштабирования. Не говоря о том, что подобное объявление (в силу специфики вашей реализации) с точки зрения ООП - будет весьма абсурдным.