简单的Arquillian测试,以启动和停止部署的应用程序

时间:2013-02-04 20:23:53

标签: java tomcat integration-testing jboss-arquillian

我正试着把头包裹在Arquillian周围,甚至可能在我的项目中开始使用它。我有一个简单的Java Web应用程序,它作为WAR部署到Tomcat。

在我的项目中,我定义了一个ServletContextListener impl,以便在Tomcat启动和停止应用程序时可以执行代码。

我正在尝试编写一个使用ShrinkWrap的超简单 Arquillian测试类,并且:

  1. 确认我的捆绑WAR可以部署到Tomcat并在不抛出异常的情况下启动;和
  2. 应用程序运行后可以访问一个简单的系统属性(ServletContextListener检查);和
  3. 确认当Tomcat关闭时,不会抛出任何异常(干净关闭)
  4. 此外,我实现ServletContextListener的类称为AppLifecycleManager

    public class AppLifeCycleManager implements ServletContextListener {
        private String logLevel;
    
        // Injected by Guice, but that's not really relevant for this question.
        @Inject
        private Logger logger;
    
        // Getter and setter for logLevel and logger
    
        @Override
        public void contextInitialized(ServletContextEvent event) {
            logLevel = System.getProperty("log.level");
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent event) {
            logger.info("Peacefully shutting down the application.");
        }
    }
    

    到目前为止,这是我最好的尝试:

    @RunWith(Arquillian.class)
    public class MyFirstRealIntegrationTest {
        @Deployment
        public static Archive<?> createDeployment() {
            // Haven't figured this part out yet, but for the sake of
            // this question lets pretend this returns a properly-packaged
            // WAR of my web app, the same that my Ant build currently produces.
        }
    
        @Test
        public void shouldBeAbleToStartTomcatWithoutExceptions() {
            // Given
            Archive war = createDeployment();
    
            // When - deploy war to Tomcat container
            try {
                // ??? how to access/init a Tomcat container?
                TomcatContainer tomcat = new TomcatContainer(); // this is wrong
                tomcat.start();
            } catch(Throwable throwable) {
                // Starting the container should not throw exceptions
                Assert.fail();
            }
        }
    
        @Test
        public void shouldBeAbleToStopTomcatWithoutExceptions {
            // Same setup as above test but stops tomcat and checks for
            // thrown exceptions. Omitted for brevity.
        }
    
        @Test
        public void shouldHaveAccessToSysPropsOnceRunning() {
            // Here, deploy to the container and start it.
            // Then, confirm that AppLifecycleManager correctly read
            // the log.level system property.
    
            // Given
            Archive war = createDeployment();
            TomcatContainer tomcat = new TomcatContainer();
    
            // When - AppLifeycleManager should now read the system property
            tomcat.start();
    
            // Then - make sure log.level was set to "DEBUG" and that it was
            // correctly read by AppLifeCycleManager.
            Assert.assertTrue(war.getClass(AppLifeCycleManager.class)
                    .getLogLevel().equals("DEBUG"));
        }
    }
    

    所以,根据我的方法,我立即遇到了几个问题:

    1. 我不确定如何访问/实例化我的Tomcat容器,以便它甚至可以启动/停止
    2. 我不确定如何从我的运行/部署的Web应用程序中实际执行测试。在上面的第3个测试中,我使用war.getClass(AppLifeCycleManager.class).getLogLevel()尝试访问“实时”类实例并检查其logLevel属性的运行时值,但我知道这是错误的。
    3. 所以我问:一个穿着战斗的Arquillian老手怎么会写这3个简单的测试,我怎样才能从JUnit测试中对我的“运行”web应用程序进行测试?提前谢谢。

2 个答案:

答案 0 :(得分:2)

我不认为你应该在测试中处理tomcat的启动/关闭。如果您使用嵌入式tomcat容器,我会更容易:https://docs.jboss.org/author/display/ARQ/Tomcat+7.0+-+Embedded。在这种情况下,arquillian将处理tomcat的启动和关闭。

您应该在使用@Deployment注释的方法中创建部署。请阅读以下指南:http://arquillian.org/guides/getting_started/

答案 1 :(得分:1)

你快到了。 createDeployment为您管理嵌入式容器的生命周期(自动启动和停止虚拟容器)。这样,你只关注测试本身。要编写集成测试,没有“框架”或“Arquillian API”来编写代码。您只需按照主代码的方式调用类和方法。

这里的关键是:您的测试实际上是在容器内运行的。如果发生异常,或者断言失败,Arquillian运行器会抛出异常并停止容器。对于您的代码示例,您正在测试是否可以读取系统属性:

@RunsWith(Arquillian.class)
public class MyArquillianTest {
    @Deployment
    public Archive<?> createDeployment() { ... }

    @Test
    public void shouldBeAbleToReadSysPropAtStartup() {
        Assert.assertTrue(System.getProperty("log.level") != null);
    }
}

请记住,Assert.assertTrue(System.getProperty("log.level") != null) Arquillian将您的代码“传输”到您为其配置的容器中。因此断言实际上是在已部署的容器内运行。