2013-02-04 34 views
0

我試圖圍繞Arquillian包裹我的頭,也許甚至開始在我的項目中使用它。我有一個簡單的Java Web應用程序,作爲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. 我不知道如何真正從我跑步/部署的Web應用程序中執行測試。在上面的第三個測試中,我使用war.getClass(AppLifeCycleManager.class).getLogLevel()嘗試訪問「實時」類實例並檢查其屬性的運行時值,但我知道這是錯誤的。

所以我問:一位身穿戰衣的Arquillian老兵會如何編寫這3個簡單的測試,以及我如何從JUnit測試中對我的「正在運行」的Web應用程序執行測試?提前致謝。

回答

1

你幾乎就在那裏。 createDeployment爲您管理您的嵌入式容器的生命週期(自動啓動和停止虛擬容器)。那樣,你只關注測試本身。要編寫集成測試,不需要編寫「框架」或「Arquillian API」。您只需以主代碼的方式調用類和方法即可。

這裏的關鍵是:您的測試實際上是在容器內運行。如果發生異常,或者如果斷言失敗,Arquillian runner將拋出異常並停止容器。爲了您的代碼示例,您正在測試,看看你是否能讀系統屬性:

@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是「運送」你的代碼中配置它的容器內。所以這個assert實際上是在你部署的容器中運行的。

2

我不認爲你應該在你的測試中處理tomcat的啓動/關閉。如果你使用嵌入式tomcat容器,我會容易得多:https://docs.jboss.org/author/display/ARQ/Tomcat+7.0+-+Embedded。在這種情況下,arquillian將處理tomcat的啓動和關閉。

您應該在用@Deployment註釋的方法中創建部署。請閱讀以下指南:http://arquillian.org/guides/getting_started/

+0

Thanks @cremersstijn(+1) - 對你的回答有幾點想法:(1)你能否確認我正確理解Arquillian的角色/功能; Arquillian允許您將應用程序的內存中版本「部署」到其內存版本的容器中? (2)通過讓Arquillian處理啓動和關閉,我明白你的意思,但是對於我的實際測試呢?我將如何編寫我的'shouldHaveAccessToSysPropsOnceRunning'測試?我認爲看到這個簡單的例子會爲我帶來很多燈泡。再次感謝! – IAmYourFaja

+0

1)「它的內存版本的容器」:它取決於,如果容器適配器是「嵌入」,它將在內存中,如果類型是「託管」,arquillian將啓動和關閉您擁有的容器安裝,如果類型是遠程的,arquillian只需連接到這個服務器,你應該啓動這種類型的容器。 – cremersstijn

相關問題