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
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. –
@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? –
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. –