Arquillian測試框架快速上手教程 (一)
阿新 • • 發佈:2019-02-10
本系列教程共五篇,分別是:
二、JBoss Forge、ShrinkWrap快速指南
五、使用 Arquillian 在雲端進行測試
其中,Web容器以JBoss-as-7.1.1為例,工程以maven目錄結構為準。
本文所涉及到的內容有:
1. Arquillian
2. Maven
3. JUnit
4. Seam Framework
5. ShrinkWrap
6. JBoss Forge
Arquillian簡介
Arquillian是一個基於JUnit,由JBoss開發的新型測試框架,其主要目的是簡化Java專案整合測試和功能測試的編寫,讓它們能像單元測試一樣簡單。Arquillian能真正在Web容器中執行測試,它主要通過三種方式與容器進行互動: 1. 嵌入式(embedded)。Arquillian和Web容器在同一個JVM中執行。 2. 受管理的(managed)。由Arquillian決定何時啟動、關閉Web容器以便向容器中部署、執行測試。 3. 遠端的(remote)。開發者事先啟動Web容器,Arquillian連線該容器並將測試部署到容器中執行。一個最簡單的單元測試
建立maven工程
這裡我們使用JBoss Forge來幫助我們快速建立maven標準目錄和基本的pom.xml檔案。 首先啟動Forge:forge
新建專案 arquillian-demo,指定包名為cn.demo:
new-project --named arquillian-demo --topLevelPackage cn.demo
這裡就用這2條命令,我們將會手動編輯pom檔案來新增arquillian的相關依賴。關於Forge的詳細安裝、使用方法,參見我另一篇文章:Debian-7.1下JBoss Forge + Arquillian測試環境搭建 為了方便編輯,我們將該專案匯入至eclipse中: 在eclipse選單欄中選擇 File --> Import,在彈出的對話方塊中選擇 "Existing Maven Project"。這樣匯入的好處是Eclipse會自動分析pom.xml檔案,自動根據依賴設定classpath,寫錯了也能第一時間得到錯誤提示。
新增Arquillian相關依賴
<modelVersion>4.0.0</modelVersion> <groupId>cn.demo</groupId> <artifactId>arquillian-demo</artifactId> <version>1.0.0-SNAPSHOT</version> <repositories> <repository> <id>JBOSS_NEXUS</id> <url>http://repository.jboss.org/nexus/content/groups/public</url> </repository> </repositories> <build> <finalName>arquillian-demo</finalName> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.6</source> <target>1.6</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>
我們需要新增 dependency 和 dependencyManagement節點,修改完成後內容如下:
<modelVersion>4.0.0</modelVersion>
<groupId>cn.demo</groupId>
<artifactId>arquillian-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
<repositories>
<repository>
<id>JBOSS_NEXUS</id>
<url>http://repository.jboss.org/nexus/content/groups/public</url>
</repository>
</repositories>
<build>
<finalName>arquillian-demo</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<!-- newly add starts -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.1.3.Final</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<!-- newly add ends -->
儲存後,eclipse會自動從遠端倉庫中下載相關jar包,稍等即可。
編寫Bean和測試類
我們首先編寫一個Hello類,內容如下:package cn.demo;
public class Hello {
public String sayHello(String name) {
return "hello," + name;
}
}
該類的功能非常簡單,傳入一個名字,然後輸出 hello + 名字。下面我們為這個類寫單元測試。 新建HelloTest類,程式碼如下:
package cn.demo;
import javax.inject.Inject;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(Arquillian.class)
public class HelloTest {
@Inject
private Hello helloBean; // 注入一個Hello物件
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class).addClass(Hello.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Test
public void isHelloValid() {
Assert.assertNotNull(helloBean); // 判斷注入是否成功
Assert.assertEquals("hello,Neo", helloBean.sayHello("Neo")); // 判斷返回值是否正確
}
}
程式碼說明: 一個Arquillian測試必須有三部分內容,分別是: 1. @RunWith(Arquillian.class)註解。 2. 一個公有的、靜態的、標註了@Deployment註解並返回一個Test Archive(稍後說明)的方法。 3. 至少有一個方法標有@Test註解。 @RunWith(Arquillian.class)註解的功能是通知 JUnit 讓 Arquillian 接過控制權,做為測試的控制器(Test Controller)。那@Deployment是做什麼用的呢?前面說過,Arquillian可以將測試直接部署到JBoss中執行,那怎麼部署,部署哪些內容,就由這個標有@Deployment註解的方法來決定。Arquillian使用 ShrinkWrap API 來建立jar包、向jar包中新增資源(比如一個類),然後 ShrinWrap 會根據我們定義好的jar包生成一個真正的jar檔案,最後由Arquillian把這個jar包部署到JBoss中去。本例中,首先呼叫ShrinkWrap類的靜態方法 create(),傳遞 JavaArchive.class 以指定我們要建立的是jar型別的檔案,然後呼叫 addClass() 方法向jar檔案中新增類,呼叫 addAsManifectResource() 方法向jar中新增一個空的 beans.xml,最後將結果返回。關於ShrinkWarp的詳細使用方法,參見官方的快速指南。
新增容器介面卡(Container Adapter)
Container Adapter是溝通 Arquillian 和 Web容器的橋樑,Arquillian 通過不同的 Container Adapter 來判斷到底在哪種Web容器上執行測試,並通過它來控制容器。只要一個Web容器有其對應的Container Adapter,那麼這個容器說可以執行 Arquillian測試。我們以remote方式的 JBoss-As-7.1.1(即開發者需事先啟動JBoss,Arquillian會自動連線這個JBoss以執行測試)為例: 首先向pom.xml中新增profiles節點,內容如下:<profiles>
<profile>
<id>arq-jbossas-remote</id>
<dependencies>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-arquillian-container-remote</artifactId>
<version>7.1.1.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.protocol</groupId>
<artifactId>arquillian-protocol-servlet</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
</profiles>
這裡用profile的一大好處是,我們可以靈活的切換不同的Web伺服器。比如,我們想在JBoss上跑測試,就執行
mvn test -Parq-jbossas-remote
如果我們想在GlassFish上執行測試,就可以定義一個名為 arq-glassfish-remote的profile,然後執行:
mvn test -Parq-glassfish-remote
執行測試
切換到工程根目錄下,執行mvn clean install -Dmaven.test.skip=true
注: -Dmaven.test.skip=true 的意思是讓maven在執行clean install指令時不要進行測試。
mvn test -Parq-jbossas-remote
輸出結果如下,則測試成功。(別忘了要事先啟動JBoss!)
以managed方式執行測試
前面說過Arquillian可以以managed 的方式與JBoss進行互動,特點是我們不必事先啟動JBoss,而在執行測試時,Arquillian會自動啟動JBoss,並在完成測試後自動關閉JBoss。下面舉例說明如何操作。 首先,新建一個profile節點,內容如下:<profile>
<id>arquillian-jbossas-managed</id>
<dependencies>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-arquillian-container-managed</artifactId> <!-- 注意這裡換成了managed而不是remote -->
<version>7.1.1.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.protocol</groupId>
<artifactId>arquillian-protocol-servlet</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
然後,為了讓Arquillian “知道” 我們的JBoss放在哪, 我們需要在 main/src/resource 目錄下建立一個名為 arquillian.xml的檔案,通過這個檔案我們可以設定 arquillian 的很多屬性,類似於 web.xml 的功能。 arquillian.xml內容如下:
<arquillian xmlns="http://jboss.org/schema/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://jboss.org/schema/arquillian
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="jbossas-managed" default="true">
<configuration>
<property name="jbossHome">你的JBoss安裝目錄</property>
</configuration>
</container>
</arquillian>
切換到專案根目錄下,執行
mvn test -Parquillian-jbossas-managed
從控制檯輸出可以看到,到 test 階段時,Arquillian 會啟動JBoss :
然後部署並執行測試,最後undeploy並關閉JBoss:
在我們的ftc的seam專案中如何使用Arquillian?
事實上,seam-2.3已經在pom檔案自動加入Arquillian的相關依賴了。我們可以直接在 ftc-test 模組中寫測試類,然後執行mvn test -P你起的profile名
即可進行測試。但seam-2.3中預設使用TestNG而不是JUnit,所以還需要對pom檔案進行修改。直接把ftc聚合模組的pom.xml改成下面的內容即可:
<?xml version="1.0" encoding="UTF-8"?>
4.0.0cnftc1.0-SNAPSHOTpomrailway safety monitorrailway safety monitorhttp://dz.sdut.edu.cn/redmineftc-ejbftc-webftc-earftc-testsJBoss repositoryhttp://repository.jboss.org/nexus/content/groups/public/phantomjsftcslow12.01.6.17.1.1.Final0.5.8.2012071112201.6.2*firefoxproxyhttp://localhost:8080http://localhost:818014444localhost030000false${project.build.directory}/ftest-logs${project.build.directory}/ftest-output300truesrc/test/resources-ftestlocalhost/${project.build.finalName}/${env.JBOSS_HOME}/server/all${env.JBOSS_HOME}default${env.CATALINA_HOME}falseUTF-81.61.6${maven.compiler.target}${maven.compiler.source}postgresqlpostgresql9.1-901-1.jdbc44.111.1.2.Finalorg.jboss.arquillianarquillian-bom1.1.2.Finalpomimportorg.jboss.arquillian.extensionarquillian-drone-bom1.2.3.Finalpomimportorg.jboss.arquillian.seleniumselenium-bom2.39.0pomimportcn.ftcftc-ejb${project.version}ejbcn.ftcftc-web${project.version}warcn.ftcftc-ear${project.version}org.jboss.seambom2.3.0.Finalpomimportcommons-loggingcommons-logging1.1.1providedcommons-collectionscommons-collections3.2providedcom.google.guavaguava${guava.version}org.slf4jslf4j-log4j12${slf4j.version}${jdbc.groupId}${jdbc.artifactId}${jdbc.version}testjavax.enterprisecdi-apiprovidedorg.jboss.spec.javax.annotationjboss-annotations-api_1.1_specprovidedjunitjunittestorg.jboss.arquillian.junitarquillian-junit-containertestorg.jboss.arquillian.graphenegraphene-webdriver2.0.1.Finalpomtestarquillian-demomaven-compiler-plugin3.11.61.6UTF-8maven-ear-plugin2.7org.codehaus.mojobuild-helper-maven-plugin1.7maven-resources-plugin2.5org.jboss.as.pluginsjboss-as-maven-plugin7.3.Finaldeploymaven-ejb-plugin2.33.0maven-war-plugin2.1.1truefalse${project.build.finalName}firefoxfirefoxchromechromearq-jboss-as-remoteorg.jboss.asjboss-as-arquillian-container-remote7.1.1.Finaltestorg.jboss.arquillian.protocolarquillian-protocol-servlettestarq-jboss_as_managed_7.xmaven-surefire-plugin2.14.1JBOSS_AS_MANAGED_7.Xorg.jboss.asjboss-as-arquillian-container-managed7.1.1.Final
然後將ftc-test 模組中的pom.xml 檔案修改為以下內容:
<?xml version="1.0" encoding="UTF-8"?>
4.0.0ftccn1.0-SNAPSHOTcn.ftcftc-testsftc Integration Tests Module (EE6)cn.ftcftc-ejbejbtestorg.slf4jslf4j-log4j12testorg.hibernate.javax.persistencehibernate-jpa-2.0-apiorg.jboss.spec.javax.facesjboss-jsf-api_2.1_specsrc/test/resources
以上修改在後續的功能測試中會用到。