Monday, September 15, 2008

sources of information

to stay up to date of what's going on mainly in the java space, different developers have different strategies. in this post i'll describe mine. my strategy consists of two parts. one part is keeping track of news and information coming from different sources, the other part is storing the important bits and pieces of information for personal use.


my primary source of information is reading news and blogs from the internet. i collect these news as feeds (rss or atom) with google reader. currently i have registered about 20 feeds, which i group in the first place by categories as 'daily feeds' and 'none daily feeds'. i try to read all the incoming 'daily feeds' every day, while i read the others when i get the time to. some of my favorite daily feeds are from dzone, theserverside, javalobby, slashdot, ibm developerworks and sun developer center. many of these news i mainly skip through - probably about 80 percent. of the remaining 20% there are sometimes some items which are especially interesting to me. i store these in google reader by marking them with a star. some posts on special topics (currently for example javafx or scala) i store in separate categories.


another information store is my google mail account. whenever i find any special articles outside of my news feeds or other documents/tutorials (e.g. in pdf format) i store links to these or the documents themselves in my google mail account. sometimes i also create link collections on a special topic. i store a set of keywords with each mail. currently i'm also trying out a personal wiki(mediawiki) for a better structuring of these collected information than it is possible with emails.


another source of information is, of course, books. i don't read books on a regular basis, but i read about three or four books a year. the latest were 'effective java', 'hibernate in action' and 'pojos in action'.


last but not least i listen to the java posse podcast, which is really great.


so all inall this might seem a lot of information. but actually i have a lot of time driving to work and home again by train.

Tuesday, September 2, 2008

Maven Integration Tests with Jetty and Selenium

in this post i'll describe how to configure maven to run integration tests with selenium and the maven-jetty-plugin. although this solution works, there surely are some points where it could be optimized (leave comments!). this solution assumes you have a maven-project configured for a web-application that can be run with the jetty plugin for maven. also, i assume that you have selenium/junit tests set up.

overview
this solution works in the following way:

  1. create two maven modules: one for the webapp, one for the integration tests

  2. install the war-file of the webapp to your maven repository

  3. in the integration test project set up the selenium/junit tests

  4. configure the surefire plugin to run the tests only in the integration-test phase

  5. use the maven-dependency plugin to download and unpack the war-file to the target directory of the integration-test project

  6. run the unpacked webapp with the jetty plugin

  7. start the selenium server with the selenium plugin

  8. run the integration tests



the details



set up the multi-module project

first of all, make your maven project a multi-module project in order to run the integration tests in a separate module apart from you ordinary junit tests. so you'll have three projects: a webapp-parent project, a webapp (war) project and a webapp-integration-tests (jar) project. for more information on setting up a multi-module project see the definitive guide to maven. here are excertps of the projects' poms:

webapp-parent pom.xml:

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>de.foo.webapp</groupId>
<artifactId>webapp-parent</artifactId>
<packaging>pom</packaging>
<name>WebApp Parent</name>
<version>1.0</version>
<modules>
<module>../webapp</module>
<module>../webapp-integration-tests</module>
</modules>
...


webapp pom.xml. the webapp-integration-tests is like this but packaging is jar:

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>de.foo.webapp</groupId>
<artifactId>webapp</artifactId>
<packaging>war</packaging>
<name>WebApp</name>
<parent>
<groupId>de.foo.webapp</groupId>
<artifactId>webapp-parent</artifactId>
<version>1.0</version>
</parent>
...


unpack the war file

in most cases the maven jetty plugin is used to run the the project it is configured for as a webapp. in this case we'll configure the jetty plugin in the integration-tests project to run the webapp project's generated war-file. to do so, the web app war has to be installed to your local repository (run mvn install). this war file can be fetched and unpacked in the integration-tests project with the maven dependency plugin:


<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>dependency-maven-plugin</artifactId>
<executions>
<execution>
<id>get war</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>de.foo.webapp</groupId>
<artifactId>webapp</artifactId>
<version>1.0</version>
<type>war</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/webapp/webapp</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
...


set up the jetty plugin

first, tell the jetty plugin to run the unpacked war-file by placing a jetty.xml file in the src/test/resources folder of the integration-tests project which defines the webapp directory. you can use the default jetty.xml and set the webAppDir parameter to point to the target directory:
<Set name="webAppDir">target/webapp</Set>
. then in the pom.xml configure the jetty plugin to run in the pre-integration-test phase.


<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<daemon>true</daemon>
<webApp>target</webApp>
<jettyConfig>target/test-classes/jetty.xml</jettyConfig>
</configuration>
<executions>
<execution>
<id>start jetty server</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run-war</goal>
</goals>
</execution>
</executions>
</plugin>
...


you can try maven integration-test or maven jetty:run-war to see if this works as expected (set the daemon parameter to false before trying this).




set up the selenium plugin

the selenium plugin then starts a selenium server in the pre-integration-test phase, too. keep in mind that the configured maven goals run in the order they were defined in the pom.

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>selenium-maven-plugin</artifactId>
<executions>
<execution>
<phase>pre-integration-test</phase>
<goals>
<goal>start-server</goal>
</goals>
<configuration>
<background>true</background>
</configuration>
</execution>
<execution>
<id>stop selenium server</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop-server</goal>
</goals>
</execution>
</executions>
</plugin>


set up the tests

next, move your integration tests to src/test/java in the integration-tests project. these can be run with the maven surefire plugin. this has to be configured to run the tests only in the integration-test phase.


<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skipTests>false</skipTests>
</configuration>
</execution>
</executions>
</plugin>


that's it. call maven integration-test to run the tests.