Monday, October 27, 2014

Debugging Junit tests (in Eclipse)

Let me start my first blog post with what most of the developers don't do:  Writing unit tests.  Just kidding.

Every developer knows the importance of the unit tests.  Before a functionality is implemented, unit tests must be written and it will help to design the implementation effectively.  This post is not about writing the tests.  It is about how to debug the unit tests.

Often times, you may wonder how to find out what is wrong in my test and why it fails.  Debugging it is one of finding what is going wrong.  This post shows how to debug the junit tests using Maven surefire plugin.


Prerequisites:



  1. Setup a Eclipse project using maven artifact.
  2. Make sure pom.xml has  the following entries:

                      <dependency>
                         <groupId>junit</groupId>
                         <artifactId>junit</artifactId>
                         <version>4.10</version>
                         <scope>test</scope>
                      </dependency>

             and

                     <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <version>2.5</version>
                        <inherited>true</inherited>
                        <configuration>
                            <forkMode>always</forkMode>
                            <trimStackTrace>false</trimStackTrace>
                            <argLine>-Xmx1024m</argLine>
                        </configuration>
                     </plugin>

Note: The plugin version may vary.
         
      
To debug the unit tests, follow these steps:



  1. The surefire plugin allows to run the tests using -Dmaven.surefire.debug option.  This option will open the port 5005 as a debug port.
  2. Using Maven Debug Configuration... create the configuration as shown here:


  3. Then using a remote java application option, create a dummy configuration in Eclipse "Remote Java Application" section.   The port is usually 5005.  The server name is 'localhost'.


  4. Then run the configuration created in step 2).  Make sure you set breakpoints in the test code.  The test get deployed and halt with the message "Listening for transport dt_socket at address: 5005".
  5. Run the configuration created in 2) as "Debug as...", then choose the entry under "Remote Java Application".
  6. The execution will stop at the breakpoint.  Now you can debug the unit tests as you do with the regular java code.

Gotchas:

  • If you kill the remote java application, it will not terminate the maven surefire plugin.  It is a separate process so it will just run the current test case and when it is about to run the second test case, it will halt with the message "Listening for transport dt_socket at address: 5005".
  • If you terminate the remote java application configuration forcibly (by pressing the "Stop" icon in Eclipse), the java process will not be terminated.  Next time if you try to run the maven configuration, it will complain "Address already in use".  You need to terminate the java process manually.