2013-02-04 4 views
0

Я пытаюсь обернуть голову вокруг Аркиллиана и, возможно, даже начать использовать его в своем проекте. У меня есть простое веб-приложение Java, которое развертывается как WAR для Tomcat.Простой тест Arquillian для запуска и остановки развернутого приложения

В моем проекте я определяю ServletContextListener impl, чтобы я мог выполнять код, когда Tomcat запускает и останавливает приложение.

Я пытаюсь написать супер-простого 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. Я не уверен, как на самом деле выполнить тесты внутри моей запущенной/развернутом веб-приложение. В третьем тесте выше я использовал war.getClass(AppLifeCycleManager.class).getLogLevel(), чтобы попытаться получить доступ к экземпляру класса «live» и проверить его значение времени исполнения logLevel, но я знаю, что это неправильно.

Итак, я спрашиваю: как проигравший в битве ветеран Аркиллиан напишет эти 3 простых теста и как я действительно буду выполнять тесты на моем «рабочем» веб-приложении из теста JUnit? Заранее спасибо.

ответ

1

Вы почти у цели. createDeployment управляет жизненным циклом вашего встроенного контейнера для вас (автоматически запускает и останавливает виртуальный контейнер). Таким образом, вы просто сосредотачиваетесь на самих тестах. Чтобы написать свои интеграционные тесты, нет никакого «фреймворка» или «аркиллианского API» для кодирования. Вы просто называете классы и методы так, как это делает ваш основной код.

Ключевое значение здесь: ваши тесты фактически запущены внутри контейнера. Если возникает исключение или если ваш аргумент терпит неудачу, аркиллианский бегун выдает исключение и останавливает контейнер.Для примера кода, где вы тестируете, чтобы увидеть, если вы можете прочитать свойство системы:

@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 является «транспортировка» код внутри контейнера настроенного его. Так что утверждение фактически выполняется внутри вашего развернутого контейнера.

2

Я не думаю, что вы должны справиться с запуском/выключением tomcat в своем тесте. Я бы гораздо проще, если бы вы использовали встроенный контейнер tomcat: https://docs.jboss.org/author/display/ARQ/Tomcat+7.0+-+Embedded. В этом случае arquillian будет обрабатывать запуск и завершение работы tomcat.

Вы должны создать развертывание в методе, аннотированном с помощью @Deployment. Просто прочитайте следующее руководство: http://arquillian.org/guides/getting_started/

+0

Спасибо @cremersstijn (+1) - несколько мыслей о вашем ответе: (1) Вы можете подтвердить, что я правильно понимаю роль/функцию Аркиллиана; что Arquillian позволяет «развернуть» версию вашего приложения в памяти в своей версии контейнера в памяти? И (2) Я понимаю, что вы имеете в виду, позволяя Arquillian обрабатывать запуск и завершение работы, но как насчет моих фактических тестов? Как я могу написать тест 'shouldHaveAccessToSysPropsOnceRunning'? Я думаю, что, увидев, что простой пример превратит в меня много лампочек. Еще раз спасибо! – IAmYourFaja

+0

1) «на встроенную в память версию своего контейнера»: это зависит, если адаптер контейнера «встроен» в то, что он будет в памяти, если тип «управляется» arquillian запустит и выключит контейнер, который у вас есть установленный, и если тип удален, arquillian просто подключитесь к этому серверу, вы должны запустить этот тип контейнера. – cremersstijn