Arquillian + Maven

My very first blog post. To be honest I've said for months that I was going to start doing this but there just always seems to be something more "urgent". Today I promised someone on the forums that I would write this one -- so maybe this will get the ball rolling for me.

DISCLAIMER: I did this several months ago so I am not sure how much has changed since then. It worked great for all the Liferay services, but it fell short for the part where I needed to mock PortletRequests etc. It is certainly possible, but there is more leg work required for that. I haven't run that marathon yet, so it won't be in this post (if that is what you are looking for). For the Liferay services though, Arquillian is a dream -- buh-bye PowerMock! 

Overview

Most of the stuff that I have found out there for Arquillian is related to using the plugins SDK and ANT. There will always be a soft spot in my heart for the Plugins SDK but in recent months my knowledge and, as a result, appreciation for Maven has really come to light. This post outlines the steps that I took to get Arquillian up and running for one of my (portlet) plugin projects.

There are a few steps.

  1. Configure your users in Tomcat
  2. Add a Connection for Arquillian
  3. Build the Maven Dependencies
  4. Configured out Project to use Arquillian
  5. Write a Unit Test

So.. let's get started.

 

Adding Users to Tomcat

In order for Arquillian to do its job, we need to give it some level of control to TOMCAT. When the unit tests are executed, Arquillian will actually deploy the plugin inside the container – which is how it has a runtime with which it can locate your dependencies from the test.

1. Go to your $TOMCAT_HOME/conf directory and open the tomcat-users.xml file. If none exists, create it. 

2. Add the following to the file.

3. Save and close the file.

 

Add Connection for Arquillian

Since Arquillian is going to use the manager application of Tomcat to deploy the plugin as part of the test execution, we need to modify our environment properties to support it.

1. Go to your $TOMCAT_HOME/bin directory and open the setenv.sh (if you are on MAC/Linux) or setenv.bat (if you are on Windows)

2. Add the following to the file.

NOTE: You can of course alter your port to use a different value other than 8099 – but this is the "default" value.

3. Save and close the file.

4. Download the tomcat manager application and upack it into the TOMCAT_HOME/webapps directory

5. Restart your TOMCAT server to make sure the changes are picked up.

 

Build Maven Dependencies

Right now the Arquillian support is, technically, has been released to the Community Edition of Liferay. On top of this, it was done first and foremost for ANT with a port to Maven coming after. It's a little tricky to get going but here is what I did. 

1. Add the following mirror to your local maven settings.xml

2. Save and close the file.

3.Go to a location on your drive where you download git projects. I use /opt/git as a root for anything I clone.

4. At the command line type: git clone https://github.com/arquillian/arquillian-extension-liferay

5. Once the repository has been cloned, go into the  arquillian-extension-liferay directory

6. Execute the maven install goal with: mvn install– which should build the library and place it into your local repo.

 

Configure Our Project to use Arquillian

Almost there, just a couple steps to go. Naturally, in order to use Arquillian we need to tell our project about its existence. First and foremost we'll need to add the dependencies to our pom.xml – but most likely this will eventually more to the master parent pom.xml file so that you don't have to include it every time you create a new plugin. Second we're going to create a configuration file to tell Arquillian where to find out Liferay server and what the credentials are. It must go in a specific location AND that location must be listed as a SOURCE folder for the project. 

1. Open the pom.xml for your project, or if you have one that you use locally, the parent pom.xml for all your projects, and add the following dependency management node just above your listed dependencies.

2. Add the following dependencies.

 

3. Save and close the file.

4. Now add a folder called integration under the /src/test folder.

5. In there create a new file called arquillian.xml and place the following contents (adjusting values based on your settings).

6. Save and close the file.

7. Now just double check to make sure that it is listed as a source folder. Click on the name of your project and then hit ALT-ENTER. You should see this --

8. Click on the tab marked Source.

9. Check to see if there is a reference to the /test/integration folder. If there is not, then click the Add ... button, and select the integration folder.

 

 

Write a Unit Test

1. Click on the /test/java folder and create a new test class – I called mine ArquillianPortletTest (because my project was named arquillian-portlet).

2. Make the body of the class the following, adjusting the name and package to whatever your class is.

Note that all I have done is used the syntactic sugar that is provided by Arquillian by marking my test class with an annotation to tell the runtime that this test should run inside the Arquillian container. What we don't see here is that the Liferay dependency automatically provides us with the ShrinkWrap we need that contains the portal services. If you look at the Arquillian documentation you will see that normally you need to write a method decorated with @Deployment that will be used to create an archive with your dependencies (but not mocks) – Liferay does this for us so all we have to do is write our tests!

3. Save the file.

4. Right click on the class and choose Run As > JUnit Test and you should get a green bar. No mocking the CounterLocalServiceUtil or the UserLocalServiceUtil.

Blogs
That's a very useful first blog post, Andew!
Do you know if this is possible with JBoss as well?
Hey Wouter -- I haven't tried it with JBoss. In fact, the person I was trying to help in the forum had JBoss as their use case. He was going to use this post as a guide and if he got it working using JBoss was going to let me know. I suggested he write his own post or let me know and I could update this one with the JBoss specifics.
Hello Andrew,

Your description is very useful.
In addition, I would like to ask you what can we do in case that you would like to use test/integration... classes like ServiceTestUtil.

Thank you
Nikos