2010-08-04 3 views
4

ПРЕДПОСЫЛКА: Моя цель состоит в том, чтобы закодировать систему TestNG-Selenium, которая работает автономно (без строк для maven или ant plugins, просто java). Он должен позволять тестовым примерам принимать параметры , включая браузер и URL-адрес домена. Когда TestRunner создает эти тестовые примеры, браузер и домен используются для получения объекта Selenium для выполнения его тестирования.Проверяет ли TestNG методы @BeforeSuite перед методами @BeforeTest?

ПРОБЛЕМА: только один тестовый класс для каждого пакета успешно получает параметр домена (в методе @BeforeSuite), прежде чем пытаться получить объект Selenium (в @BeforeTest). Испытательные классы, которые не получают домен, имеют нулевой объект selenium b/c, который не может быть создан. .

КОД: XmlClasses содержатся в их собственном XmlTest, и все три находятся в одном XmlSuite. Набор содержит в порядке TestClass1, TestClass2, а затем TestClass3. Сами тест-классы являются подклассами из 2-х слоев базовых классов , которые включают в себя функциональность для инициализации введенных переменных и впоследствии получают экземпляр Selenium. Целью этого является тестирование одного или нескольких приложений (на нескольких доменах) с минимальным повторным кодом (например: Selenium экземпляр в корневом базовом классе, поскольку он является общим для всех тестов). Подробнее см. Методы .

// Top-most custom base class 
abstract public class WebAppTestBase extends SeleneseTestBase 
{ 
     private static Logger logger = Logger.getLogger(WebAppTestBase.class); 
     protected static Selenium selenium = null; 
     protected String domain = null; 
     protected String browser = null; 

     @BeforeTest(alwaysRun = true) 
     @Parameters({ "selenium.browser" }) 
     public void setupTest(String browser) 
     { 
       this.browser = browser; 
       logger.debug(this.getClass().getName() 
           + " acquiring Selenium instance ('" + this.browser + " : " + domain + "')."); 
       selenium = new DefaultSelenium("localhost", 4444, browser, domain); 
       selenium.start(); 
     } 

} 

// Second level base class. 
public abstract class App1TestBase extends WebAppTestBase 
{ 

     @BeforeSuite(alwaysRun = true) 
     @Parameters({"app1.domain" }) 
     public void setupSelenium(String domain) 
     { 
       // This should execute for each test case prior to instantiating any Selenium objects in @BeforeTest 
       logger.debug(this.getClass().getName() + " starting selenium on domain '" + domain+ "'."); 
       this.domain = domain; 
     } 
} 

// Leaf level test class 
public class TestClass1 extends App1TestBase 
{ 
     @Test 
     public void validateFunctionality() throws Exception 
     { 
       // Code for tests go here... 
     } 
} 

// Leaf level test class 
public class TestClass2 extends App1TestBase 
{ 
     @Test 
     public void validateFunctionality() throws Exception 
     { 
       selenium.isElementPresent(... 
       // Rest of code for tests go here... 
       // .... 
     } 
} 


// Leaf level test class 
public class TestClass3 extends App1TestBase 
{ 
     @Test 
     public void validateFunctionality() throws Exception 
     { 
       // Code for tests go here... 
     } 
} 

ВЫХОД: TestCase3 работает правильно. TestCase1 и TestCase2 терпят неудачу. Трассировка стека генерируется ...

10:08:23 [DEBUG RunTestCommand.java:63] - Running Tests. 
10:08:23 [Parser] Running: 
    Command line suite 
    Command line suite 

[DEBUG App1TestBase.java:49] - TestClass3 starting selenium on domain 'http://localhost:8080'. 
10:08:24 [DEBUG WebAppTestBase.java:46] - TestClass2 acquiring Selenium instance ('*firefox : null'). 
10:08:24 [ERROR SeleniumCoreCommand.java:40] - Exception running 'isElementPresent 'command on session null 
10:08:24 java.lang.NullPointerException: sessionId should not be null; has this session been started yet? 
     at org.openqa.selenium.server.FrameGroupCommandQueueSet.getQueueSet(FrameGroupCommandQueueSet.java:216) 
     at org.openqa.selenium.server.commands.SeleniumCoreCommand.execute(SeleniumCoreCommand.java:34) 
     at org.openqa.selenium.server.SeleniumDriverResourceHandler.doCommand(SeleniumDriverResourceHandler.java:562) 
     at org.openqa.selenium.server.SeleniumDriverResourceHandler.handleCommandRequest(SeleniumDriverResourceHandler.java:370) 
     at org.openqa.selenium.server.SeleniumDriverResourceHandler.handle(SeleniumDriverResourceHandler.java:129) 
     at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1530) 
     at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1482) 
     at org.openqa.jetty.http.HttpServer.service(HttpServer.java:909) 
     at org.openqa.jetty.http.HttpConnection.service(HttpConnection.java:820) 
     at org.openqa.jetty.http.HttpConnection.handleNext(HttpConnection.java:986) 
     at org.openqa.jetty.http.HttpConnection.handle(HttpConnection.java:837) 
     at org.openqa.jetty.http.SocketListener.handleConnection(SocketListener.java:245) 
     at org.openqa.jetty.util.ThreadedServer.handle(ThreadedServer.java:357) 
     at org.openqa.jetty.util.ThreadPool$PoolThread.run(ThreadPool.java:534) 

Я ценю любую информацию, которую вы можете иметь по этому вопросу.

ответ

8

Я думаю, проблема заключается в том, что ваш метод @BeforeSuite присваивает значение полю, но у вас есть три разных экземпляра, поэтому остальные два никогда не инициализируются.

Помните, что @BeforeSuite запускается только один раз, независимо от того, к какому классу он принадлежит. Таким образом, методы @ Before/AfterSuite обычно определяются в классах, которые находятся за пределами всей тестовой среды. Эти методы должны быть действительно статичными, но я решил не применять это требование, потому что это иногда нецелесообразно.

Я думаю, что лучший способ приблизиться к вашей проблеме - это посмотреть на свое доменное поле в качестве внедренного ресурса, который каждый ваш тест получит от Guice или другой среды инъекций зависимостей.

+0

Спасибо за быстрый ответ. Я изменил свою реализацию соответственно. – Aaron

+0

спасибо, мне тоже помогло –

Смежные вопросы