Est-ce que les méthodes TestNG garantie de @BeforeSuite sont exécutées avant @BeforeTest méthodes?

StackOverflow https://stackoverflow.com/questions/3407514

  •  25-09-2019
  •  | 
  •  

Question

CONTEXTE: Mon objectif est de coder un système testng-Sélénium qui fonctionne AUTONOME (Pas de chaînes à Maven ou plugins fourmi, il suffit de java). Il doit tenir compte des cas de test à accepter paramètres, y compris le navigateur et l'url de domaine. Lorsque le TestRunner instancie ces cas de test, le navigateur et le domaine sont utilisés pour obtenir un objet Sélénium pour effectuer il teste.

PROBLÈME: Une seule classe d'essai par la suite réussit à obtenir le paramètre de domaine (dans un méthode @BeforeSuite) avant de tenter d'obtenir un objet Sélénium (dans un @BeforeTest). Les classes de test qui ne reçoivent pas le domaine ont un objet sélénium nulle b / c il ne peut pas être instancié.

CODE: Les XmlClasses sont contenus chacun dans leur propre XMLTest et les trois sont en une seule XmlSuite. La suite contient dans l'ordre de TestClass1, TestClass2, puis TestClass3. Les classes de test sont eux-mêmes sous-classes de 2 couches de les classes abstraites de base qui inclut des fonctionnalités pour initialiser les variables injectés et par la suite obtenir une instance de Sélénium. Le but de cela est de tester un ou plusieurs (applications sur plusieurs domaines) avec aussi peu que possible le code répété (ex: Sélénium instanciation est dans la classe de base de la racine, car il est commun à tous les tests). Voir les méthodes ci-dessous pour plus de détails.

// 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...
        }
}

SORTIE: TestCase3 fonctionne correctement. TestCase1 et TestCase2 échoue. Stack trace est généré ...

 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)

Je vous remercie de toute information que vous pourriez avoir sur cette question.

Était-ce utile?

La solution

Je pense que le problème est que votre méthode de @BeforeSuite est d'attribuer une valeur à un champ, mais vous avez trois instances différentes, de sorte que les deux autres ne sont initialisées.

Rappelez-vous que @BeforeSuite est exécuté qu'une seule fois, quel que soit la classe il appartient. En tant que tel, @ méthodes Avant / AfterSuite sont généralement définies sur les classes qui sont en dehors de l'environnement de test. Ces méthodes devraient vraiment être statiques mais je décidé de ne pas appliquer cette exigence, car il est parfois impossible.

Je pense qu'une meilleure façon d'aborder votre problème est de regarder votre champ de domaine en tant que ressource injectée que chacun de votre test recevront de Guice ou un autre cadre d'injection de dépendance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top