In part 1 of this post, I described the possible approaches/frameworks for unit testing of web applications. In this post, I concentrate on one framework, which is JBoss Arquillian. The contents of this post will be:

  • What about JBoss Arquillian?
  • Use Arquillian to Unit Test inside EClipse and JBoss 6
  • Secrets behind Scene: How Arquillian handles the Test?

 

Since the contents of this post is a little bit long, I will explain the following remained contents in part 3:

  • Using Arquillian for Unit Test from Apache Ants
  • Is Arquillian Really Good? Let's Evaluate it

 

Before jumping to details, I should mention that I am not a member of Arquillian project or JBoss. This post is only persoanl exprience of me on this framework, as a community member. So, it is not official ...

 

What about JBoss Arquillian?

As it is mentioned in official site of Arquillian:

 

 Arquillian enables you to test your business logic in a remote or 
 embedded container. Alternatively, it can deploy an archive to the
 container so the test can interact as a remote client. ...
 Arquillian can either execute a test case inside the container, in 
 which case the test class is deployed by Arquillian along with the
 code under test, or hold back the test class so it can act as a 
 remote client to the deployed code. All the developer has to do is
  write the test logic.
 

 

In four words, Arquillan is in-container test framework. For concept of in-container test, please refer to part 1 of this post.

 

Arquillian is a well-designed and easy-to-use framework, that makes the difficult task of web application unit test/integration test very easy.

You just write test cases using well-known tools of JUnit 4 or TestNG 5, and then add a few metadata to your test code specific to Arquillian, and you are done. Just need to run the test. The following difficult jobs are handled by Arquillian:

  • Build deployable archive files (jar, war, ...) containing your test case classes.
  • Deploy built test archive files to web application container, and after test, undeploy it automatically.
  • After deploy, run the test inside container, and capture test results/failure.
  • If necessary, Arquillian can handle start/stop web application container.

 

At the time of this post, it is still in 1.0.0.Alpha 5 release, and as a JBoss project, an active community and many team members are extending it to make it ready for final release. Its official site is as following:

http://www.jboss.org/arquillian

 

Use Arquillian to Unit Test inside EClipse and JBoss 6

OK, introduction is enough. Let's see how to use Arquillian in a typical unit test case. Arquillian has many rich funcationalites and support different scenarios. But, for understanding it, let's concentrate on a simple situation (although it is simple, I guess it will be enough for many test situations). Let's assume our test situation is as following:

  • As a sample, Target code to be tested is a business logic class to manage users of our web application with a simple CRUD interface like following sample code (typically, these kind of information are stored/retrieved to/from database):

 

 public class UserLogic {  
     public User add( User user ){ ... }
     public User get( Long id ){ ... }
     public Boolean update( User user ){ ... }
     public Boolean delete( Long id ){ ... }
}

 

 

  • Our application's classes/resources (including above business logic class) have been already deployed into web application server, which is JBoss 6, and the server is running (don't worry, if you are using different application server, we will talk about it too in few lines lower).
  • We are using EClipse IDE as development/coding environment, and we can deploy/debug/run the web appliction into above web application server. The meaning of this assumption is that EClipse already knows how to access into application server. (I think other IDE tools should be the same, and EClipse is only a sample. However, I have not tested other IDEs).
  • Your have necessary JUnit 4 or TestNG 5 plugin already installed into your EClipse, and you can use it. In recent versions of EClipse, these plugins have already been installed, and you shouldn't need any additional plugin.

 

That's all for the assumptions. Let's start preparing unit test items and do the test. The steps are very easy, and as following:

 

STEP (1): Write Unit Test Classes: For this step, you don't care about Arquillian, and just need knowledge of how to use JUnit 4 or TestNG 5. I assume that you already know how to do it. If not, you can find many good tutorials on web, for example, this link. Let's consider that our unit test case class will be something like following code (for JUnit 4):

 

 

 public class UserLogicTest {
        @Test
        public void testUserAdd(){
             UserLogic logic = ...;
             User user = ...;
             user = logic.add(user);
             User userFromDB = logic.get( user.getId() );
             asertNotNull("User should not be null" , userFromDB);
             assertEquals("User ID confirm" , user.getId() , userFromDB.getId());
             assertEquals("User Name confirm" , user.getName() , userFromDB.getName());
             // ... (other confirmations)
        }
 }

 

For this step, be careful about one important point. For JUnit, you should use JUnit 4.8.2 or higher. If using TestNG, you should use TestNG 5.14.9 or higher. Please confirm that your classpath library in EClipse for JUnit or TestNG is pointing out proper version, otherwise, when you run the test, you may face exception.

 

STEP (2): Add Arquillian Libraries to Your EClipse Project: Same as other Java frameworks, to use them, you need to add the necessary libraries to the library classpath of your project in EClipse. Same is for Arquillian, and you need to add Arquillian JAR files. Technically, this step should be the easiest, but, actually, this one is the most difficult step.

If you are using Apache Maven in your project, you can refer to this page of Arquillian's documentation. But, if, same as me, you are not fan of Apache Maven, logically you should be able to find the necessary JAR files in the download page of Arquillian, in this link. However, in this link, you can find it is mentioned:

 

 Right now, Arquillian releases only consist of individual binary and source JARs 
 published to the JBoss Community Nexus repository (see above). We'll make 
 distributions available for download once Arquillian enters beta.

 

If you ca't wait for Beta release of Arquillian, then you can refer to following table to download the necessary JAR files. Sorry if I can't summarize all of them in one ZIP file to make this step easy for you.

 

No.Category of LibraryJAR fileDownload Links
1JBoss Arquillian libraries (1.0.0.Alpha 5)arquillian-api-1.0.0.Alpha5.jarLink
arquillian-impl-base-1.0.0.Alpha5.jarLink
arquillian-protocol-servlet-1.0.0.Alpha5.jarLink
arquillian-spi-1.0.0.Alpha5.jarLink
arquillian-testenricher-cdi-1.0.0.Alpha5.jarLink
arquillian-testenricher-ejb-1.0.0.Alpha5.jarLink
arquillian-testenricher-resource-1.0.0.Alpha5.jarLink
2JBoss ShrinkWrap libraries (1.0.0.Alpha 12)shrinkwrap-api-1.0.0-alpha-12.jarLink
shrinkwrap-descriptors-api-0.1.4.jarLink
shrinkwrap-impl-base-1.0.0-alpha-12.jarLink
shrinkwrap-resolver-api-1.0.0-alpha-12.jarLink
shrinkwrap-spi-1.0.0-alpha-12.jarLink
3

Unit test framework (JUnit or TestNG) libraries

(include libraries for the framework you use)

junit-x.y.jar (should be higher than 4.8.2)Link
arquillian-junit-1.0.0.Alpha5.jarLink
testng-x.y.jar (should be higher than 5.14.9)Link
arquillian-testng-1.0.0.Alpha5.jarLink
4

Web application container's client libraries

(For JBoss, refer to right link.

For other web application containers, refe to this link)

jbossall-client.jar

Find in /client sub

folder of JBoss

arquillian-jbossas-remote-6-1.0.0.Alpha5.jarLink

 

As you can see in category 4 of above table, for different web application servers, the only difference is that you just need to include the related client libraries of target application server. Other steps are exactly same for all types of server.

 

STEP (3): Add Arquillian Meta-Data to Unit Test Classes: We have already included the Arquillian libraries in classpath, and we are ready to modify the unit test class we prepared in above STEP (1). The modification is very easy, and you can see the final test code in following.

 

@RunWith(Arquillian.class)
 public class UserLogicTest {
      @Deployment
      public static JavaArchive createTestArchive() {
              return ShrinkWrap.create(JavaArchive.class, "test.jar");
      }
 
     @Test
     public void testUserAdd(){
          UserLogic logic = ...;
          User user = ...;
          user = logic.add(user);
          User userFromDB = logic.get( user.getId() );
          asertNotNull("User should not be null" , userFromDB);
          assertEquals("User ID confirm" , user.getId() , userFromDB.getId());
          assertEquals("User Name confirm" , user.getName() , userFromDB.getName());
          // ... (other confirmations)
     }
}

 

 

The @RunWith(Arquillian.class) means to use the Arquillian's test runner, instead of default JUnit's test runner.

And, the static @Deployment method, means to deploy the test code to web application server, as a "test.jar" archive file.

That's all for this step. Huh, it is easy, isn't it?

 

STEP (4): Run Test Classes: Last step is to run your test cases. It is easy, and exactly same as the way you run other test case classes inside EClipse. Nothing special for Arquillian. For JUnit, you can refer to this link.

 

Enjoy it. Your test should be running and show you the results, hopefully no error.

  

Secrets behind Scene: How Arquillian handles the Test?

We have seen how to create and run the unit test classes. But, how Arquillian run the test inside container? Run your test case inside the EClipe again, and when the test is running, have a look at: /server/serverName/deploy folder of your JBoss. While unit test is running, you can see a file called "test.war" is created in the deploy folder. And when the unit test is finished, this war file is deleted automatically.

 

Huh? In the static @Deployment method (mentioned in STEP (3)), the code says that test file should be "test.jar", but, the deploy file is "test.war". Why?

 

The answer is very easy. If you unzip the "test.war" file, you can see that a "test.jar" file exists inside it, which contains your test case class. But, in addition to "test.jar", some other Arquillian JAR files also exist within "test.war" file. That is logical. Arquillian needs to run the test cases inside the application server, so, the Arquillian libraries also should be deployed into server.

 

In order to run in-container test, Arquillian do following tasks sequentially for each test case:

  • Bundle the test class and related Arquillian library JAR files into an archive file (according to static @Deployment method)
  • Deploy the test archive into web application server
  • Enhance/enrich the test class (e.g., resolving @Inject, @EJB and @Resource injections) and run the test class within server, and return the test results
  • Undeploy the test archive from web application server

 

To be exact,  other than "enhance/run/return results of test classes", other tasks are all done by JBoss ShrinkWrap. You have already seen in above STEP (2), that ShrinkWrap JAR libraries are necessary. To be more exact, ShrinkWrap internally uses the SPI (Service Provider Interface) to support deploy/undeploy archive files into/from web application server. You can read about SPI more in details in this link. Anyway, let's thank develppers of the Arquillian framework who have done good job to handle such difficult implementations internally, that we don't need to learn SPI.

 

OK. This long post is reaching to the end. By reading this post, I think you have found enough knowledge of how to use Arquillian. Arquillian has many advanced functionalities, that you can read in the documentation page. In part 3, I will explain about how to run Arquillian test cases from Apache Ant's xml files.