Aiming to Make Testing Easier
Integration Tests with Arquillian - Part 3
More Container Functions
In a similar manner as described above you can test almost any container functionality with Arquillian, with the Stateless EJBs being the simplest case. It becomes more complicated when the runtime with the appropriate resources (eg a database or interface) must be supplied or if Context and Dependency Injection (CDI) is required. But even for such requirements Arquillian has a solution. The simplest case is the use of CDI. To enable CDI with your testcase you simply have to add an empty beans.xml file to the test archive. This is achieved by:
From now on CDI functions are accessible because test.jar contains the required beans.xml in the META-INF folder. Another option is the use of an appropriate beans.xml with content. For this purpose, it has to be put into the project's resources directory and referenced accordingly:
Up to now everything we tested was done using the GlassFish Embedded API. If you are hoping to test your Java Persistence API (JPA) applications you have to switch the container because these are only supported with the remote GlassFish container. This requires the entire Arquillian configuration to be changed. The remote deployment is backed by the JSR-88 API. If you are looking for some good examples you can consult the Arquillian User Guide.
Arquillian basically manages to test everything which could be directly injected or by facilitating the CDI features. In addition to the previous example, you can also use it to test JMS connections. For this it's as simple as adding the appropriate queues, topics and connection factories:
Arquillian as a Client
Having tests for the external system representations, is as important as focusing on application testing from the inside. You should spend as much time on the interfaces which people or programs use to interact with your application. Typically it should be ensured that each application and its execution path is fully tested. Third parties can interact with the application through various interfaces, such as Web Services, EJBs, or remote via http. If you are taking care of this you have to consider a lot of things, like object serialization and network connections. In order to test this view onto the environment Arquillian provides two modes: IN_CONTAINER and AS_CLIENT. The IN_CONTAINER mode corresponds to the examples shown above. The AS_CLIENT allows checking the outside view of an application. Running the AS_CLIENT mode is as simple as adding another Annotation to your testcase:
In a direct comparison with the fashion IN_CONTAINER the client tries to fashion as few tasks to perform in the container and natural to act as a client. The @Deployment method simply controls the container's lifecycle.
Debugging, and Eclipse Integration
If you don't like the painful cmd-line maven execution of your Arquillian tests, you are free to integrate it into your favorite IDE as long as it is Eclipse or NetBeans or has any Maven integration at all. Eclipse requires you to use the m2eclipse plugin. You need to activate the relevant Maven profile, and you can start using Run As | JUnit Test to run individual tests from the IDE. NetBeans doesn't require a separate plugin. It has Maven support since version 6.8. Here too, the active Maven Profile needs to be added. The configuration is already done. Debugging basically follows the same characteristics as with other deployed applications. Test-runner and tests run in a different JVM than the container itself. Therefore, the debugger has to be attached to the correct JVM. Details about this can be found in the container documentation of your choice.
It's lots of fun to use Arquillian. There is nothing comparable on the market in terms of seamless container integration. It's simple enough to use and not too hard to configure. Simple test cases can be created in minutes. Tradeoff is, that it quickly becomes complex. The configuration of the container is only one area. The more complex your deployments get (e.g. dependent libraries, special classpath configuration) the harder the setup. And Arquillian is still an Alpha version which is not finished at the time of writing. Some things simply don't work at the moment. If you are running into trouble it could consume your time very quickly.
To find out where exactly the problem is, you need time and knowledge. The core of Arquillian doesn't log too much. To find a real fault is not easy. But the project is not complete yet. A couple of features are already announced. In addition to Method Interceptors the so-called Arquillian Resources should become available with the next release. That will make any container-specific objects (such as the initial context) inject able via a generic @ArquillianResource annotation. Support for other containers is also on the list of things to come.
It will be exciting and worth further observation. The project is slightly behind schedule and it should come up with the next development milestone soon.