Using Groovy for Unit Tests Inside Eclipse

I have blogged before in the past about using Groovy to write Eclipse Plugins. In fact, I think I am the only person in the world to ever write about the subject ever. This lack of interest in the subject is unfortunate for many reasons, but one reason in particular is the fact that writing in Groovy as opposed to Java can make many plugin related tasks simpler, particularly a lot of the tasks that make writing plugins no fun. For this specific reason, I am considering giving giving Groovy EMF a hard look as part of my ongoing efforts to make sense out of the Eclipse EMF Project. In my opinion, EMF could be like Grails if the generated code were in Groovy instead of Java.

Still I wanted to focus the blog entry on the use of Groovy for Unit Tests inside of Eclipse. This is because, in my opinion, that writing Unit Tests in Groovy is one of the main entry points for a Java developer to get their feet wet with Groovy and to see its benefits (the other two cases, in my opinion once again, are XML document parsing/generation and scripting). So here goes.
 

Framing the problem

The trouble with using Groovy in your projects is the same for using it for Unit Tests as when using it in production code from within Eclipse. The problem is that you usually have a build process that is run from the command line, often referred to as headless mode that you use for continuous integration or releases, and then you have the incremental build process that runs from within Eclipse. For headless (or batch/command line) builds, there is support from Groovy to assist with this, first there is the groovyc command that is equivalent to javac and second there is the Groovyc Ant Task. To take advantage of Eclipse incremental builds you really need to have an Eclipse plugin supporting that for you. This is where Groovy Eclipse can really be helpful, it provides the needed plugin support for incremental builds for Groovy from within Eclipse. For the next sections we will focus on solutions for utilizing Groovy for Unit tests.

 

Solution 1: GroovyTestSuite

There is a short snippet on using GroovyTestSuite from within Eclipse. There is one strong advantage to this method, since the groovy code is compiled when the AllTests are run, ostensibly this method could be used in both the headless batch build and from within Eclipse without any changes. So why not just use this method? Well there are downsides:

1. You can't use Eclipse's nice 'Recreate Test Suite' operation to keep the AllTests suite in sync. Over time, this is one of those problems that will bite more than once and usually when you least expect it.

2. If you don't have unit test classes compiled to classfiles, it makes running individual test cases difficult. This is something you feel more when you are trying to get a particularly challenging testcase to pass, in addition to the added compilation time, you will have to run the suite again. Of course you could create a new JUnit Testsuite just for the testcase you are trying to run, but then don't forget to delete it when done and don't check it into your source repository.

3. You have to make an assumption as to the current working directory. If you notice in the example code for GroovyTestSuite you have to assume that the unit test runner is being run from the project source directory. This is fine for Eclipse, just remember to check if that assumption holds for your batch/headless build as well.

4. You have to make assumptions as to the testcase's package. Once again refer to the code example for GroovyTestSuite. In the example see that the source directory, the package path is hardcoded, and the groovy file name is hardcoded. This is fine as long as you never change the source directory or refactor your test code into other groovy files or java packages, (*sarcasm alert*) which will never happen right? Now admittedly if you run your unit tests early and often, you will see this and then you will go and fix them immediately. Still better to not have to make those assumptions right?

5. Be careful about making Groovy code dependent on Java code or vice versa from within the same Eclipse Java project. This is a problem shared with the second approach as well. It is something you must consider (I know that groovyc will now compile Java code as well and it should be evaluated for use from within Groovy Eclipse or from your external build processes). There are a couple of ways to deal with the issue as I currently understand it. First, if you write only Groovy or Java code in a test project, there is no problem. This is usually an ok solution for greenfield test writing, but will not hold long term. Secondly, since there are no generated classfiles from groovy code in your project, you cannot allow your Java code to rely on any groovy code in the same test project period.

Solution 2: Groovy Eclipse Plugin

There is another option from within Eclipse, install the Groovy Eclipse Plugin and then add the Groovy builder and nature to your JUnit test project. Why do this? Well Groovy Eclipse will compile your Groovy code to classfiles and place them in a class folder for Eclipse so that Eclipse sees the compiled code as just another set of compiled Java code. This means that GroovyTestSuite is unnecessary and that running tests will not incur the full costs of compilation at start time, a significant advantage for developers. Another advantage is that the unit tests are compiled, so it is possible to easily run one testcase at a time. If setup correctly, using the Groovy Eclipse plugin makes developing/using Unit Tests in Groovy as seamless and invisible as possible. "So", you may ask, "ok Groovy Eclipse fan boy, what are the tradeoffs?" First off, even though I am a Groovy Eclipse committer and supporter, I am very well aware of its shortcomings, so I am not a fan boy. Secondly, well here are the tradeoffs/issues with this approach.

1. You must include Groovy as part of your batch/headless build process to compile the Groovy Unit Tests first, before the Unit tests are run. This is the same trouble you have if you are using Groovy in your production code. I will refer you to the section above titled 'Framing the Problem', for approaches on dealing with this. Using GroovyTestSuite only requires access to the groovy libraries at runtime.

2. Be careful about making Groovy code dependent on Java code or vice versa from within the same Eclipse Java project. This is not a problem unique to Groovy Eclipse or to writing Unit Tests with Groovy, but it is something you must consider (I know that groovyc will now compile Java code as well and it should be evaluated for use from within Groovy Eclipse). There are a couple of ways to deal with the issue as I currently understand it. First, if you write only Groovy or Java code in a test project, there is no problem. This is usually an ok solution for greenfield test writing, but will not hold long term. Secondly, be careful and avoid the following circumstances, A.groovy depends on B.java which depends on C.groovy or A.java depends on B.groovy which depends on C.java. This is an issue that needs to be addressed in Groovy Eclipse generally, either by leveraging groovyc to compile Java code or do an analysis to provide an Error/Warning marker to the user about the above circumstances. A useful heuristic traditionally is to allow groovy code to depend on java code or java code to depend on groovy code but not vice versa in the same project. If you hold to that heuristic, just consider the issue raised by number 3.

3. The order of the builders in the .project file. First off if you have groovy code depending on java code or vice versa in the same project, make sure that the groovy builder is before or after the java builder in the .project file. This can be easily checked by right clicking the project and then bringing up the properties dialog. Just look for the Builders section, you can easily remove, add, or reorder the builders in your .project file. Secondly, there are other occasions to be careful about the build order. In particular, this one bit me yesterday when I was trying to write a couple of unit tests for Eclipse monkey in groovy. I was pulling my hair out and about to give up on groovy unit tests for monkey (I mentioned I am not a Groovy Eclipse fanboy didn't I?), when I remembered to check the builder order. Sure enough, the groovy builder came after the plugin and manifest builders. Reordering the groovy builder to come before the PDE builders then allowed the PDE JUnit to actually run (Note to self: add better PDE support for Groovy Eclipse).


Conclusion


There are advantages and disadvantages to both approaches to writing Unit Tests for your projects from within Eclipse. The first approach, at first, seems more straightforward and simple, in particular no integration with external builds, compilation of groovy code is reduced to a classpath resolution problem. The second approach, using Groovy Eclipse, leaves the developer with the need to integrate Groovy into their external build processes, but in the longer term provides a more seamless and productive experience. So if you are wanting to write Unit Tests in groovy, give Groovy Eclipse a try!  

From http://iacobus.blogspot.com/

0

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Serge Bureau replied on Wed, 2008/06/11 - 7:00am

Thank you for the info,

 

I am looking to using Groovy for testing, it definitely looks very promising. 

James Ervin replied on Wed, 2008/06/11 - 11:56am in response to: SergeBureau

My pleasure, especially if I can help you and others avoid the pitfalls I have already come across.

Serge Bureau replied on Thu, 2008/06/12 - 7:27am

Although it is not the fault of Groovy per se, the integration with Eclipse and NetBeans is far from top notch.

 

It compiles and Run, but for testing it is a pain. I will take a look at Idea that looks more promising.

 

Open soure continues to offer half-baked solutions, working but not refined.

I can't understand Netbeans better support for foreign languages like Ruby instead of Groovy.

 

Take a look at a developper environment like the one for the IPhone, and then see how old NetBeans and Eclipse really look. Not much has changed in the last 10 years ??? 

Kristian Mandrup replied on Fri, 2008/06/13 - 2:40pm

I agree that EMF with Groovy/Grails has great potential. Check out this page

http://docs.codehaus.org/display/GRAILS/2008/03/12/MDA+for+Groovy+using+EMF

"Some work for using Open ArchitectureWare (oAW) for generating Grails applications has already been done and is available on the Fornax Platform. Don't know if you are aware of that.
There is a Grails cartridge which can be downloaded from here (http://www.fornax-platform.org/cp/display/fornax/Grails+%28CGR%29). "

 I experimented with having the Domain Model and validation logic defined in one or more XML files (to be generated from XMI/EMF fx using OAW). There is still a lot of potential redundancy in a Domain model, Testing code etc. that could be avoided IMO. The upcoming OAW 5 should be awesome! Already the recent 4.3 is very promising!

It would be cool to have a Groovy DSL for writing Eclipse plugins... There is the GroovySWT for starters.

Cheers!

Kris

Mark Haniford replied on Wed, 2008/06/18 - 4:49pm in response to: SergeBureau

I'm with Serge on this about the Groovy support in Netbeans.  But I can postulate on the reasoning behind it.  JRuby is for all intents and purposes "owned" by Sun - as in they have the two main developers on the payroll.  NIHS seems to be alive and well.

Serge Bureau replied on Thu, 2008/06/19 - 9:00am in response to: mark haniford

I see your point !

 

This is unfortunate, it is why even if Netbeans is nice it does not provide developper's what they want.

Sun's thinks it knows better, but their lack of vision is getting boring. 

James Ervin replied on Thu, 2008/06/19 - 2:18pm

Well it is a bit off topic now, but I will comment.  I think there is probably a mentality at Sun to think they need to win more people over to the Java platform.  That thinking leads them to wanting to support Ruby and Ruby on Rails on the Java platform.  This is not the end of the world or necessarily bad thinking, since you would think the more developers on the Java platform the "mo' better" right?  But what about the people who are already on the Java platform doing their work? 

Groovy/Grails is native to the Java platform and should be easier to support on the Java platform.  Groovy/Grails has a far flatter (read easier) learning curve for existing Java developers.  So therefore, I think Groovy/Grails is something that should be better supported to help keep developers on the Java platform.  Remember there is no Groovy/Grails outside the JVM and Java platform libraries.  Besides the fact that Groovy/Grails support should be far easier to achieve than Ruby/RoR support, there is the converse argument about JRuby and JRuby on Rails (JRoR?).  JRuby on Rails could also be viewed as a conduit for allowing development to leave the Java platform as well.  Why?  Well all new work could feasibily be run on native Ruby platforms and, in fact, would probably run better on native Ruby platforms.

So the question is, is it more important to convert others to the Java platform or is it more important to keep the large Java developer base on the Java platform?  My answer is yes.  You can't just grow a community, you must also take care of what is already there.  So please Sun, get past the NIH (Not Invented Here) syndrome and go hire a Groovy guy next to Mr. Nutter (no complaints for Mr. Nutter, he has been doing good stuff on the JVM for dynamic languages, thanks man).   You wont regret it.

I think I should expand this to a blog entry, it ended up far longer than I first intended....

Thomas Corbin replied on Mon, 2008/07/14 - 6:00pm

But netbeans will gain groovy/grails support later this fall with nb 6.5, and in fact the milestone 1 for nb 6.5 supposedly contains groovy/grails support. And spring support, and hibernate support, and ..., and ... In any case, the groovy support will be built on the language infrastructure built for ruby.

James Ervin replied on Tue, 2008/07/15 - 1:07pm in response to: tcorbin

Good for Netbeans.  When it releases I will try and make a point of checking it out.  But Netbeans is outside the scope of this blog entry and discussion.  Still I would be interested to see how much of the infrastructure is reusable from Ruby to Groovy.  Also, it is nice that Sun is taking Groovy more seriously as well.

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.