@BeforeClass注释在远程服务器上使用Arquillian时调用方法两次

Chr*_*ams 7 java testng jboss jboss-arquillian

我们正在从使用带有嵌入式JBoss的TestNG过渡到使用带有远程服务器的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();
    }

}
Run Code Online (Sandbox Code Playgroud)

这基本上给了我这样的输出:

从正在执行mvn的控制台:

in setupOnce(): false
Run Code Online (Sandbox Code Playgroud)

从jboss服务器:

in setupOnce(): true
in setupComponents: true
in testGetUser: true
Run Code Online (Sandbox Code Playgroud)

Mar*_*rga 5

这是"预期"的行为.不是很好,但这是Arqullian的工作原理.

JUnit的

  • @BeforeClass/@AfterClass仅在ClientSide上执行
  • 测试类的状态在@Test之间丢失,在容器中,每个测试重复整个生命周期
  • 根据runmode(客户端/服务器)执行@Before/@After

TestNG的

  • 一切都在服务器和客户端上运行