shrinkwrap_Java EE 6测试第二部分– Arquillian和ShrinkWrap简介
shrinkwrap
在Java EE 6測試的第一部分中,我簡要介紹了使用Glassfish嵌入式容器的EJB 3.1 Embeddable API,以演示如何啟動該容器,如何在項目類路徑中查找bean以及運行非常簡單的集成測試。這篇文章重點介紹Arquillian和ShrinkWrap以及為什么它們是用于企業Java應用程序集成測試的出色工具。
GitHub上的arquillian-shrinkwrap文件夾下提供了用于此文章的源代碼。
工具
Arquillian- 管理一個或多個容器的生命周期
- 將測試用例,相關類和資源捆綁為ShrinkWrap檔案
- 將檔案部署到容器
- 通過依賴注入和其他聲明式服務豐富測試用例
- 在容器內部(或針對容器)執行測試
- 將結果返回給測試跑步者進行報告
ShrinkWrap是Arquillian的核心組件,它提供了一種簡單的機制,可以通過友好,流利的API來組合JAR,WAR和EAR等檔案。
使用Arquillian的主要好處之一是,您可以在遠程容器(即應用程序服務器)中運行測試。 這意味著您將測試真實的交易 。 沒有嘲笑。 甚至沒有嵌入式運行時!
議程
這篇文章將涵蓋以下主題:
- 在基于Maven的Java項目中配置Arquillian基礎架構
- 直接在測試實例中注入EJB和托管Bean(CDI)
- 測試Java持久性API(JPA)層
- 在客戶端模式下運行Arquillian
- 在IDE中運行和調試Arquillian測試
配置Maven以運行集成測試
為了與Maven進行集成測試,我們需要一種不同的方法。 通過不同的方法,我的意思是不同的插件: Maven故障安全插件 。
故障安全插件是Maven Surefire插件的分支,旨在運行集成測試。
Failsafe插件目標旨在在集成測試階段的程序包階段之后運行。
Maven生命周期有四個運行集成測試的階段:
- 集成前測試:在此階段,我們可以啟動任何所需的服務或執行任何操作,例如啟動數據庫或啟動Web服務器,等等。
- 集成測試:故障安全將在此階段運行測試,因此在所有必需的服務啟動之后。
- 集成后測試:關閉所有服務的時間…
- 驗證: failsafe運行另一個在此處解釋測試結果的目標,如果沒有通過任何測試,failsafe將顯示結果并退出構建。
在POM中配置故障保護:
<!-- clip --> <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.12</version><configuration><skipTests>true</skipTests></configuration> </plugin> <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-failsafe-plugin</artifactId><version>2.12</version><configuration><encoding>UTF-8</encoding></configuration><executions><execution><id>integration-test</id><goals><goal>integration-test</goal></goals></execution><execution><id>verify</id><goals><goal>verify</goal></goals></execution></executions> </plugin> <!-- clip -->默認情況下,Surefire插件執行**/Test*.java , **/*Test.java和**/*TestCase.java測試類。 Failsafe插件將查找**/IT*.java , **/*IT.java和**/*ITCase.java 。 如果您同時使用Surefire和Failsafe插件,請確保使用此命名約定,以使其更容易識別哪個插件正在執行哪些測試。
在Maven中配置Arquillian基礎架構
通過附加以下XML片段,將Maven項目描述符配置為使用Arquillian:
<!-- clip --> <repositories><repository><id>jboss-public-repository-group</id><name>JBoss Public Repository Group</name><url>http://repository.jboss.org/nexus/content/groups/public/</url></repository> </repositories><dependencyManagement><dependencies><dependency><groupId>org.jboss.arquillian</groupId><artifactId>arquillian-bom</artifactId><version>1.0.1.Final</version><scope>import</scope><type>pom</type></dependency></dependencies> </dependencyManagement><dependencies><dependency><groupId>org.jboss.arquillian.testng</groupId><artifactId>arquillian-testng-container</artifactId><scope>test</scope></dependency><dependency><groupId>org.testng</groupId><artifactId>testng</artifactId><version>6.4</version><scope>test</scope></dependency><dependency><groupId>org.jboss.spec</groupId><artifactId>jboss-javaee-6.0</artifactId><version>3.0.1.Final</version><scope>provided</scope><type>pom</type></dependency> </dependencies><profiles><profile><id>jbossas-remote-7</id><activation><activeByDefault>true</activeByDefault></activation><dependencies><dependency><groupId>org.jboss.as</groupId><artifactId>jboss-as-arquillian-container-remote</artifactId><version>7.1.1.Final</version><scope>test</scope></dependency></dependencies></profile> </profiles> <!-- clip --> Arquillian有大量的容器適配器 。 Arquillian測試可以在與測試中使用的編程模型兼容的任何容器中執行。 但是,在本文中,僅使用JBoss AS 7。 
 與Java EE 6測試第1部分類似,我選擇使用TestNG測試框架,但同樣, JUnit應該也能正常工作。 
創建可測試的組件
 在研究如何使用Arquillian編寫集成測試之前,我們首先需要有一個要測試的組件。 
 會話Bean是Java EE堆棧中的常見組件,將用作測試主題。 在本文中,我將創建一個非常基本的后端,用于向數據庫中添加新用戶。 
 在上面的代碼中,我使用JPA ,因此我們需要一個持久性單元。 
 持久性單元定義由應用程序中的EntityManager實例管理的所有實體類的集合。 這組實體類表示單個數據存儲中包含的數據。 
 持久性單元由persistence.xml配置文件定義: 
在此示例中,我使用的示例數據源使用H2數據庫,并且已經使用JBoss AS 7進行了配置。
最后,我們還需要一個映射到數據庫中表的實體:
@Entity public class User {@Id@GeneratedValueprivate Long id;@NotNullprivate String name;// Removed constructors, getters and setters for brevity@Overridepublic String toString() {return "User [id=" + id + ", name=" + name + "]";} }使用Arquillian測試JPA
 現在,我們都準備編寫我們的第一個Arquillian測試。 
 一個Arquillian測試用例看起來就像一個帶有一些額外功能的單元測試。 它必須具有三件事: 
- 擴展Arquillian類(這特定于TestNG,對于JUnit,您需要在類上使用@RunWith(Arquillian.class)批注)
- 用@Deployment注釋的公共靜態方法,該方法返回ShrinkWrap存檔
- 至少一種使用@Test注釋的方法
 該測試很簡單,它插入一個新用戶并檢查id屬性是否已被數據庫生成的值填充。 
 由于Arquillian豐富了該測試,因此您通常可以使用@EJB或@Inject批注來注入EJB和受管bean。 
 用@Deployment注釋的方法使用ShrinkWrap來構建一個JAR歸檔文件,該歸檔文件將部署到容器中并對其進行測試。 ShrinkWrap將測試所需的類和資源與類路徑的其余部分隔離開來,您應該包括測試所需的每個組件才能在部署存檔中運行。 
客戶端模式
Arquillian支持三種測試運行模式:
- 容器內模式用于測試您的應用程序內部。 這使Arquillian能夠與測試進行通信,豐富測試并遠程運行測試。 在這種模式下,測試在遠程容器中執行; Arquillian默認使用此模式。
- 客戶端模式用于測試客戶端如何使用您的應用程序。 與重新包裝并覆蓋測試執行的容器內模式相反,客戶端模式的作用盡可能小。 它不會重新打包@Deployment也不會將測試執行轉發到遠程服務器。 您的測試用例正在JVM中按預期運行,并且您可以自由地從外部測試容器,如客戶所見。 Arquillian唯一要做的就是控制@Deployment的生命周期。
- 混合模式允許在同一測試類中混合兩種運行模式。
要以客戶端模式運行Arquillian,首先要構建要測試的servlet:
@WebServlet("/User") public class UserServlet extends HttpServlet {private static final long serialVersionUID = -7125652220750352874L;@Injectprivate UserServiceBean service;@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/plain");PrintWriter out = response.getWriter();out.println(service.addUser(new User("Ike")).toString());out.close();}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {doGet(request, response);} }現在讓我們測試一下:
public class UserServletIT extends Arquillian {private static final Logger LOGGER = Logger.getLogger(UserServletIT.class.getName());// Not managed, should be used for external calls (e.g. HTTP)@Deployment(testable = false)public static WebArchive createNotTestableDeployment() {final WebArchive war = ShrinkWrap.create(WebArchive.class, "example.war").addClasses(User.class, UserServiceBean.class, UserServlet.class).addAsResource("META-INF/persistence.xml")// Enable CDI.addAsWebInfResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml"));LOGGER.info(war.toString(Formatters.VERBOSE));return war;}@RunAsClient // Same as @Deployment(testable = false), should only be used in mixed mode@Test(dataProvider = Arquillian.ARQUILLIAN_DATA_PROVIDER)public void callServletToAddNewUserToDB(@ArquillianResource URL baseURL) throws IOException {// Servlet is listening at <context_path>/Userfinal URL url = new URL(baseURL, "User");final User user = new User(1L, "Ike");StringBuilder builder = new StringBuilder();BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));String line;while ((line = reader.readLine()) != null) {builder.append(line);}reader.close();assertEquals(builder.toString(), user.toString());} }盡管此測試非常簡單,但是它允許您使用單個方法調用來測試應用程序的多個層。
在Eclipse中運行測試
您可以從IDE內部運行Arquillian測試,就像單元測試一樣。
運行Arquillian測試
(點擊圖片以放大)
- 安裝TestNG和JBoss Tools Eclipse插件。
- 將新的JBoss AS服務器添加到Eclipse:
- 啟動JBoss AS服務器:
- 從Eclipse運行測試用例,右鍵單擊Project Explorer上的測試文件,然后選擇
Run As > TestNG Test :
結果應類似于以下內容:
調試Arquillian測試
(點擊圖片以放大)
 由于我們使用的是遠程容器,因此Debug As > TestNG Test不會導致斷點被激活。 
 相反,我們需要以調試模式啟動容器并附加調試器。 這是因為測試是在與原始測試運行器不同的JVM中運行的。 
 調試測試所需要做的唯一更改是在調試模式下啟動JBoss AS服務器: 
- 啟動JBoss AS服務器調試模式:
- 將所需的斷點添加到代碼中。
- 并通過右鍵單擊Project Explorer上的測試文件并選擇它來調試它
Run As > TestNG Test :
更多資源
 我希望能夠強調Arquillian的一些好處。 
 有關Arquillian的更多信息,請查看以下資源: 
- Arquillian指南
- Arquillian社區
- Arquillian Git存儲庫
相關文章
- 單元測試JBoss 5服務
- Java EE 6測試第I部分– EJB 3.1可嵌入API
- Maven 2 Cobertura插件–更新
- JBoss PojoCache配置
- JBoss AS 5.0已經發布!
- 上一篇文章:Java EE 6測試第I部分– EJB 3.1可嵌入API
- 下一篇文章:比較OpenDDR與WURFL
參考: Java EE 6測試第二部分–來自我們JCG合作伙伴 Samuel Santos的Arquillian和ShrinkWrap簡介,位于Samaxes博客上。
翻譯自: https://www.javacodegeeks.com/2012/06/java-ee-6-testing-part-ii-introduction.html
shrinkwrap
總結
以上是生活随笔為你收集整理的shrinkwrap_Java EE 6测试第二部分– Arquillian和ShrinkWrap简介的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 勾子基本概念
- 下一篇: 21 | 哈希算法(上):如何防止数据库
