【问题标题】:Simple Arquillian test to start and stop deployed app简单的 Arquillian 测试来启动和停止部署的应用程序
【发布时间】:2013-02-04 20:23:53
【问题描述】:

我正试图围绕 Arquillian 展开思考,甚至​​可能开始在我的项目中使用它。我有一个简单的 Java Web 应用程序,它作为 WAR 部署到 Tomcat。

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

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

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

另外,我实现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 应用程序中实际执行测试。在上面的第三个测试中,我使用war.getClass(AppLifeCycleManager.class).getLogLevel() 尝试访问“实时”类实例并检查其logLevel 属性的运行时值,但我知道这是错误的。

所以我问:一个身经百战的 Arquillian 老兵将如何编写这 3 个简单的测试,以及如何从 JUnit 测试中对我的“正在运行”的 Web 应用程序执行测试?提前致谢。

【问题讨论】:

    标签: java tomcat integration-testing jboss-arquillian


    【解决方案1】:

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

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

    【讨论】:

    • 感谢@cremersstijn (+1) - 关于您的回答的一些想法:(1)您能否确认我正确理解了 Arquillian 的角色/功能; Arquillian 允许您将应用程序的内存版本“部署”到其容器的内存版本? (2) 我明白你让 Arquillian 处理启动和关闭的意思,但是我的实际测试呢?我将如何编写我的shouldHaveAccessToSysPropsOnceRunning 测试?我认为看到这个简单的例子会为我打开很多灯泡。再次感谢!
    • 1)" 到其容器的内存版本":这取决于容器适配器是否“嵌入”在内存中,如果类型是“托管”,arquillian 将启动并关闭一个你已经安装的容器,如果类型是远程的,arquillian 只需连接到这个服务器,你应该启动这个类型的容器。
    【解决方案2】:

    你快到了。 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 正在将您的代码“传输”到您为其配置的容器内。所以这个断言实际上是在你部署的容器中运行的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多