2012-04-19 9 views
7

verwendet Wir wechseln von dem Verwenden von TestNG mit einem eingebetteten JBoss, um Arquillian mit einem Remoteserver zu verwenden.@BeforeClass-Annotationen, die Methoden zweimal aufrufen, wenn Arquillian auf Remote-Server

Wir führen einen einfachen Test aus, bei dem eine Methode mit @BeforeClass annotiert ist, die eine Testkonfiguration durchführt. Nach vielen Ausgrabungen sieht es so aus, als ob diese Setup-Methode zweimal aufgerufen wird: einmal auf der Konsole, wo wir unseren Maven-Befehl ausführen, um den Test auszuführen, und erneut, wenn der Testkrieg auf unserem Remote-Server implementiert wird und der Test ausgeführt wird. Dies sind zwei separate JVMS - eine läuft außerhalb des Containers und eine andere läuft innerhalb des Containers. Ich bevorzuge es, letztere laufen zu lassen.

Ist das das Verhalten, das ich erwarten sollte oder gibt es etwas, das ich vermisse?

Momentan prüfen wir gerade, ob wir im Container sind oder nicht, und wenn ja, führen wir unseren Setup-Code aus. Das funktioniert, aber ich würde gerne wissen, ob es einen besseren Weg gibt.

Einige Codeschnipsel (bitte ignorieren Sie die Einfachheit des Codes und die Tatsache, dass die Methode setupComponents hier wirklich nicht benötigt wird, es gibt viel kompliziertere Tests, die wir migrieren, die diese Funktionalität benötigen):

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(); 
    } 

} 

Diese im Grunde gibt mir Ausgabe, die diese wie folgt aussieht:

Von der Konsole, in der MVN ausgeführt wird:

in setupOnce(): false 

Vom jboss-Server:

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

Ab sofort '@ BeforeClass' soll nur auf dem Client für Arquillian Tests auszuführen. Aber das sieht wie ein Fehler aus. Könnte bitte diese Frage mit deinem Code aktualisieren? Hinweis: [ARQ-351] (https://issues.jboss.org/browse/ARQ-351) übernimmt die Kontrolle für die Ausführung von Lebenszyklusereignissen. –

+0

@VineetReynolds, der Code ist sehr einfach. Ich werde ein Snippet veröffentlichen. Wenn das erwartete Verhalten in der Zukunft nur "@BeforeClass" außerhalb des Containers ausführen soll, wie kann ich eine Methode mit Anmerkungen versehen, die dazu führt, dass sie im Container, aber vor allen Tests dieser Klasse ausgeführt wird? –

+0

Auch @VineetReynolds, wenn Sie anstelle Ihres Kommentars eine Antwort posten und eine alternative Lösung hinzufügen möchten, damit Sie eine Gutschrift erhalten, tun Sie es bitte. –

Antwort

5

Dies ist "erwartet" Verhalten. Nicht wirklich nett, aber so funktioniert Arqullian.

JUnit

  • @BeforeClass/@AfterClass nur auf Clientside ausgeführt
  • Der Zustand der Testklasse ist verloren zwischen @Test, in Behälter die gesamte Lebensdauer für jeden Test wiederholt wird
  • @Before/@After auf der RunMode ausgeführt je (Client/Server)

TestNG

  • alles sowohl auf Server- und Client ausgeführt wird
+0

Nach dem Post ist das im Grunde die Antwort, die ich vom Arquillian-Team bekommen habe.Es gibt einige (an dieser Stelle) offene Fragen zu Arquillian, die dieses Thema abdecken: https://issues.jboss.org/browse/ARQ-567 https://issues.jboss.org/browse/ARQ-197 –