Тесты падают после прохождения первого тестового класса


(Дмитрий Назаренко) #1

В автоматизации совсем недавно.Пользуюсь 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)

заранее спасибо за помощь:smile:


#2

код stop() покажи
гадать пока не буду но мне кажется после стопа ты убиваешь драйвер и перед новым тестом его не подымаешь


(Дмитрий Назаренко) #3

вот код как поднимается/убивается браузер

	public ApplicationManager(Properties properties){       
		String browser = properties.getProperty("browser");
		if("firefox".equals(browser)){
			driver = new FirefoxDriver();	
		}else if ("ie".equals(browser)){
			driver = new InternetExplorerDriver();
		}else if ("chrome".equals(browser)){
			driver = new ChromeDriver();
		}else{
			throw new Error("Unsupported browser:" + browser);
		}
		
		baseUrl = properties.getProperty("baseUrl");
	    driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
		driver.get(baseUrl);
	  	}
	
	 public void stop() {
		driver.quit();
	    }

(Дмитрий Назаренко) #4

могу ошибаться, поправите если не прав. Анотации @Before\After отвечают за то то, по какой логике будет подниматься\убиваться драйвер. У меня указано @BeforeTest/AfterTest,соответственно перед тестовыми классами и после.По этому драйвер вообще не должен убиваться...Поправте если не прав.


(Roy Obenon) #5

А сам то драйвер это поле класса ApplicationManager?


(Дмитрий Назаренко) #6

Ага


(Sergey Korol) #7

Одному мне интересно взглянуть на testng.xml? :wink: Да и как собственно происходит запуск при использовании той самой xml? Maven, руки?


(Дмитрий Назаренко) #8

Если пускать руками-то фелятся оба класса. Если мавеном то первый класс отрабатывает, а второй фейлится.
вот код 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 -->

вот на всякий случай pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>iGovAT</groupId>
  <artifactId>iGovAT</artifactId>
  <version>0.0.1-SNAPSHOT</version>
    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
  <build>
    <plugins>
      <plugin>
      <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>           
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
      
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.18.1</version>
          <inherited>true</inherited>
          
            <configuration>
          <suiteXmlFiles>
            <suiteXmlFile>testng.xml</suiteXmlFile>
          </suiteXmlFiles>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
      <dependency>
          <groupId>org.testng</groupId>
          <artifactId>testng</artifactId>
          <version>6.7</version>
          <scope>test</scope>
      </dependency>
   <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>2.48.2</version>
    </dependency> 
  </dependencies>
</project>

(Дмитрий Назаренко) #9

простите, уточню. запуск через testng.xml и maven дает один и тот же результат(первый класс проходит, второй падает)
при запуске через временный файл testng-customsuite.xml(проект-run as) падает всё


#10

а почему у вас клас нейм не совпадает с названиями тестовых классов ?


(Дмитрий Назаренко) #11

название тестовых классов соответствует указанному в testng.xml


(Sergey Korol) #12

Не совсем...


#13

@BeforeTest: The annotated method will be run before any test method belonging to the classes inside the tag is run. друг
поменяй на беформетод посмотри что получится ?


(Sergey Korol) #14

У вас 2 класса, которые наследуют TestBase. При этом экземпляр ApplicationManager создается лишь однажды. О чем речь собственно?

П.С. Либо разносите классы по разным test тэгам, либо меняйте аннотацию.


(Дмитрий Назаренко) #15

это не решение, так как в любом случае придется запускать и весь Suite и будет не один класс в тесте.
какие еще варианты?


#16

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


(Дмитрий Назаренко) #17

скорее всего не понял,поясните пожалуйста


#18

У вас 1 бефортест он запустится перед тегом тест , 1 бефор тест 1 экземпляр app!!! а надо 2 экземпляра в вашем случае для каждого тестового класса


(Дмитрий Назаренко) #19

Вы еще раз простите за глупые вопросы(только начинаю изучать автоматизацию и программирование).
с аннотацией BeforeClass конечно все будет работать, но я считаю это нерациональный подход, так как очень много времени будет занимать старт/стоп браузера каждый раз.
Вопрос: что нужно доработать в коде, что бы создавалось нужно кол-во экземпляров ApplicationManager?


(Sergey Korol) #20

Тут дело скорее в понимании основных концепций ООП и механики работы подключаемых библиотек.

На пальцах касательно ООП: у вас есть 2 тестовых класса, каждый из которых наследует TestBase, т.е. физически у вас будет 2 независимых объекта ApplicationManager при запуске.

На пальцах касательно механики работы TestNG: у вас есть xml, в котором оба класса физически являются частью "тестовой группы":

<test verbose="2" name="Test">

Далее вы в TestBase заключаете ключевой метод, отвечающий за инициализацию объекта ApplicationManager, под аннотацию @BeforeTest. Фактически, глядя на xml, вы ставите ограничение на вызов инициализатора ApplicationManager. Другими словами, он будет вызван лишь раз - при обработке первого класса. Отсюда и вытекает вполне логичный NPE, т.к. второй объект остается неинициализированным. Вся ирония в том, что вы сами это ограничение и поставили.

Исходя из того, что вас категорически не устраивает инициализация драйвера на уровне класса, выхода тут 2:

  • Не требующий изменений в коде:

<suite name="Suite">
  <test verbose="2" name="Test1">
    <classes>
      <class name="iGovTests.DocumentsTest"/>
    </classes>
  </test>
  <test verbose="2" name="Test2">
    <classes>
       <class name="iGovTests.DocumentsTest2"/>
    </classes>
  </test>
</suite>
  • Вынуждающий менять область видимости ApplicationManager:

protected static ApplicationManager app;

При этом, вы автоматически добавляете себе головной боли при потенциальном внедрении масштабирования. Не говоря о том, что подобное объявление (в силу специфики вашей реализации) с точки зрения ООП - будет весьма абсурдным.