2012-04-19 9 views
7

Stiamo passando dall'utilizzo di TestNG con un JBoss incorporato all'utilizzo di Arquillian con un server remoto.@BeforeClass annotazioni che invocano due metodi quando si utilizza Arquillian sul server remoto

Stiamo eseguendo un semplice test che ha un metodo annotato con @BeforeClass che esegue alcune impostazioni di prova. Dopo un lungo lavoro di ricerca, sembra che il metodo di installazione venga chiamato due volte: una volta sulla console in cui eseguiamo il comando Maven per eseguire il test e nuovamente quando la guerra di test viene distribuita sul nostro server remoto e il test viene eseguito. Questi sono due JVMS separati: uno in esecuzione all'esterno del contenitore e un altro in esecuzione all'interno del contenitore. La mia preferenza è di avere solo la seconda corsa.

È questo il comportamento che dovrei aspettarmi o c'è qualcosa che potrebbe mancare?

Per ora, stiamo effettivamente controllando se siamo nel container o no e, in tal caso, eseguiamo il nostro codice di installazione. Funziona, ma mi piacerebbe sapere se c'è un modo migliore.

Alcuni frammenti del nostro codice (ignorare la semplicità del codice e il fatto che il metodo setupComponents in realtà non è necessario qui, ci sono test molto più complicati che stiamo migrando che necessiterà di questa funzionalità):

public class BaseTest extends Arquillian 
{ 
    private static Log log = LogFactory.getLog(SeamTest.class); 

    @Deployment 
    public static Archive<?> createDeployment() 
    { 
     // snip... basically, we create a test war here 
    } 

    /** 
    * todo - there might be a better way to do this 
    */ 
    private boolean runningInContainer() 
    { 
     try 
     { 
      new InitialContext().lookup("java:comp/env"); 
      return true; 
     } 
     catch (NamingException ex) 
     { 
      return false; 
     } 
    } 

    @BeforeClass 
    public void setupOnce() throws Exception 
    { 
     getLog().debug("in setupOnce(): " + runningInContainer()); 
     if (runningInContainer()) 
     { 
      new ComponentTest() 
      { 
       protected void testComponents() throws Exception 
       { 
        setupComponents(); 
       } 
      }.run(); 
     } 
    } 

    public User createUser() 
    { 
     // ... 
    } 

    public Log getLog() 
    { 
     // snip... 
    } 

    public UserDao getUserDao() 
    { 
     // ... 
    } 

    public abstract class ComponentTest 
    { 
     protected abstract void testComponents() throws Exception; 

     public void run() throws Exception 
     { 
      try { 
       testComponents(); 
      } finally { 

      } 
     } 
    } 

} 

public class UserDaoTest extends BaseTest 
{ 
    UserDao userDao; 

    @Override 
    protected void setupComponents() 
    { 
     getLog().debug("in setupComponents: " + runningInContainer()); 
     userDao = getUserDao(); 
    } 

    @Test 
    public void testGetUser() throws Exception 
    { 
     getLog().debug("in testGetUser: " + runningInContainer()); 

     new ComponentTest() 
     { 
      protected void testComponents() throws Exception 
      { 
       User user0 = createUser(); 
       user0.setName("frank"); 

       userDao.merge(user0); 

       User retrievedUser = userDao.findByName("frank"); 
       assertNotNull(retrievedUser); 
      } 

     }.run(); 
    } 

} 

questo mi dà fondamentalmente uscita che assomiglia a questo:

Dalla console in cui è in esecuzione mvn:

in setupOnce(): false 

Dal server jboss:

in setupOnce(): true 
in setupComponents: true 
in testGetUser: true 
+0

A partire da ora, '@ BeforeClass' è pensato per essere eseguito solo sul client per le prove Arquillian. Ma questo sembra un bug. Potresti aggiornare questa domanda con il tuo codice? Nota: [ARQ-351] (https://issues.jboss.org/browse/ARQ-351) consentirà il controllo dell'esecuzione degli eventi del ciclo di vita. –

+0

@VineetReynolds, il codice è molto semplice. Pubblicherò uno snippet. Se il comportamento previsto in futuro è di avere solo "@BeforeClass" eseguito all'esterno del contenitore, come posso annotare un metodo che causerà l'esecuzione nel contenitore ma prima di tutti i test di quella classe? –

+0

Inoltre, @VineetReynolds, se desideri pubblicare una risposta al posto del tuo commento e includere una soluzione alternativa in modo da poter ottenere il credito, ti preghiamo di farlo. –

risposta

5

Questo comportamento è "previsto". Non proprio bello, ma è come funziona Arqullian.

JUnit

  • @BeforeClass/@AfterClass vengono eseguiti solo su lato client
  • Lo stato della classe di test si perde tra @Test, nel contenitore l'intero ciclo viene ripetuto per ogni prova
  • @Before/@After vengono eseguite a seconda della RunMode (client/server)

TestNG

  • tutto viene eseguito sia su server e client
+0

Dopo il post, questa è sostanzialmente la risposta che ho ricevuto dal team di Arquillian.Ci sono alcuni problemi di Arquillian aperti (a questo punto) che trattano questo: https://issues.jboss.org/browse/ARQ-567 https://issues.jboss.org/browse/ARQ-197 –

Problemi correlati