Аннотации @BeforeClass дважды вызывают методы при использовании Arquillian на удаленном сервере

Мы переходим от использования TestNG со встроенным JBoss к использованию Arquillian с удаленным сервером.

Мы запускаем простой тест с методом, аннотированным @BeforeClass, который выполняет некоторую настройку теста. После долгих копаний похоже, что этот метод установки вызывается дважды: один раз на консоли, где мы выполняем нашу команду Maven для запуска теста, и снова, когда война тестов развертывается на нашем удаленном сервере и выполняется тест. Это две отдельные JVMS — одна работает вне контейнера, а другая — внутри контейнера. Я предпочитаю просто запустить последний.

Это поведение, которое я должен ожидать, или я могу что-то упустить?

На данный момент мы на самом деле проверяем, находимся ли мы в контейнере или нет, и если да, мы запускаем наш код установки. Это работает, но я хотел бы знать, есть ли лучший способ.

Некоторые фрагменты нашего кода (пожалуйста, не обращайте внимания на простоту кода и тот факт, что метод setupComponents здесь действительно не нужен, есть гораздо более сложные тесты, которые мы переносим и которым понадобится эта функциональность):

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

}

Это в основном дает мне вывод, который выглядит следующим образом:

Из консоли, где выполняется mvn:

in setupOnce(): false

С сервера jboss:

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

person Chris Williams    schedule 19.04.2012    source источник
comment
На данный момент @BeforeClass предназначен для запуска только на клиенте для тестов Arquillian. Но это похоже на ошибку. Не могли бы вы обновить этот вопрос с вашим кодом? Примечание. ARQ-351 будет управлять выполнением событий жизненного цикла.   -  person Vineet Reynolds    schedule 19.04.2012
comment
@VineetReynolds, код очень простой. Я опубликую фрагмент. Если ожидаемое поведение в будущем состоит в том, чтобы @BeforeClass выполнялся только вне контейнера, как я могу аннотировать метод, который заставит его работать в контейнере, но до всех тестов этого класса?   -  person Chris Williams    schedule 19.04.2012
comment
Кроме того, @VineetReynolds, если вы хотите опубликовать ответ вместо своего комментария и включить альтернативное решение, чтобы получить кредит, сделайте это.   -  person Chris Williams    schedule 19.04.2012


Ответы (1)


Это "ожидаемое" поведение. Не очень приятно, но именно так работает Arqullian.

Юнит

  • @BeforeClass / @AfterClass выполняются только на стороне клиента
  • Состояние тестового класса теряется между @Test, в контейнере весь жизненный цикл повторяется для каждого теста
  • @Before / @After выполняются в зависимости от режима запуска (клиент/сервер)

ТестНГ

  • все запускается и на сервере и на клиенте
person MartinTeeVarga    schedule 11.06.2013
comment
После поста это в основном ответ, который я получил от команды Arquillian. Есть несколько открытых (на данный момент) проблем Arquillian, которые охватывают это: issues.jboss.org/browse /ARQ-567 issues.jboss.org/browse/ARQ-197 - person Chris Williams; 31.07.2013