In this article we are going to write a Selenium 2 test for the Liferay portlet we developed in Getting started with portals. Then we are going to add a profile to our Maven pom that, when activated, starts the Liferay server and runs the selenium 2 test after which the Liferay server is stopped again.
This is ideal for Liferay integration testing, especially when the process needs to be fully automated(e.g. no manual stop/start of server), such as by a continuous integration server like Hudson or Jenkins.

Profile breakup

1. Activation

The profile is getting activated when we supply a liferay.home.dir. However, this is not the only property we are going to need for a successful run. We need to give all the necessary info about the browser we are going to run the Selenium tests with and the server we are going to run the tests on. So, next to the liferay.home.dir, we will also need to supply the selenium.firefox.binary and the liferay.port properties.
Hence, to do an install with the profile enabled, we will need to run Maven with a goal like this:

The Cargo plugin is going to start and stop Liferay in a talled application server container. The server is started before integration testing begins and stopped after integration testing. In the configuration part of the plugin, we configure our server: where it is located, the vmargs we want to start it with, etc..
The <skip> part of the configuration means we want Cargo to run and start the server. If set to true, the execution of this plugin would be skipped and no container would be started.
The <wait> part of the configuration determines whether we want to wait after the Cargo container is started or not. If set to true, we would need to manually intervene(as in pressing some buttons) to continue the Maven process. For automated integration testing, this obviously needs to be set to false.
For more information about configuring the cargo plugin, visit the Cargo maven plugin reference.
One thing to keep in mind is that the cargo.servlet.port should be the port Liferay runs on(8080 by default). If this port is not configured correctly, Cargo will timeout because it cannot determine whether the server started or not. It is the port Cargo listens on, not the port the server starts on. The server starts on the default port listed in its own configuration files.

The above plugin deploys our war(the product of the pom) to the Liferay server. It also executes before integration testing begins. Note that in the default case, Maven plugins execute in the order in which they are defined. So in this case, the Liferay server is started first, after which the application(the portlets) is deployed to the started server.
Note that this plugin deploys the application, but it does NOT wait for the app to be deployed. Maven execution continues right away, so we will need to build something in to wait for the app to be deployed, before we actually start running the Selenium 2 tests.

The antrun plugin enables all Ant functionality within a Maven context.
This the dirty part of our profile. If there is something to improve, it is this part.
We are essentially doing two things here.
Before integration testing begins, we are waiting 300 seconds. This gives the application enough time to deploy, so it is ready once the selenium tests start running. Note that you could use something more intelligent here than plain waiting, such as polling the server to check whether a certain page is loading or even building a Liferay hook that when deployed, can be used to ask Liferay through a webservice whether it has finished deploying or not. However, that would require building something custom and is outside of the scope of this article.
The second ant execution configured for the plugin, cleans the Liferay server in the clean phase, so we start with a clean Liferay server every run. We had to add this because we were having issues with the new deploy conflicting with certain parts of an old deploy from time to time. Among other things, this makes sure the old version is not deployed first when the server starts. Same as with the other execution, one could come up with more sophisticated ways to do this, but it should be enough to illustrate the idea.

5. Surefire plugin

The surefire plugin is the default plugin to run unit tests with. Because we want to use the failsafe plugin in the next section, the execution of this plugin should be skipped. Therefore, we are setting <skip> to true.

With the failsafe plugin, we are going to run our Selenium 2 test. The main difference with the surefire plugin is that this plugin will make sure the Maven execution keeps executing is some integration tests fail.
There is also some additional configuration required.
Basically, we make a Suite class to which we add our test:

All tests defined in this suite will be run using the supplied firefox executable. Note that the path to the firefox bin is not part of the failsafe plugin, but is a system property that we are setting. This system property is then fetched within the running Selenium 2 test. Same for the Selenium base url. Note that in order to run the test (suite) successfully, you will need to add a page “testing” to your Liferay portal and make sure the portlet is deployed on that page first.
Finally, the outcome of all tests will be written to htmlfiles in the supplied reportsDirectory.

Comments

1-28-13

Richard O. Legendi says:

Hi Steffen, thanks for the great post. Is it possible to access the whole source code of this project as a zip somewhere? I’m probably having some version issues with the Selenium dependency, it would help a lot to resolve it. Thanks in advance!