Sunday, June 23, 2013

Groovy and its awesomeness on integration tests.

I know its been really a while like a year and half long since i posted something out on this side. I finally decided to stretch my thoughts out a little.

It's been close to 2 years since i came to Kansas city and I have to say I am loving the work i am doing here everyday because the scope of picking a new stuff everyday is fantastic. The biggest hurdle i faced was migrating from Visual studio to Eclipse but everything after that was smooth. I have been messing with Groovy, Ruby, dipping my feet into clojure of late. I actually wanted to start writing about clojure today but still i think i don't have enough experience with it to post a blog on it. So i will stick to Groovy for now.

Alright so what's groovy before i delve into more finer details. let me start off with a comparison here and as to what we're comparing. I am going to compare a method in java to a method in groovy.

public static long add(final long a, final long b) {
  return a+b;
}
Simple enough to add any explanation for this method, lets look at its groovy equivalent.
def add(a,b) {
 a+b;
}
First thing which stands out is the missing return type, second there is no types for the arguments passed and third there is no return statement inside the function, Groovy is a dynamic language and supports lazy evaluation where the compiler doesn't care about the types of the arguments until the runtime also the groovy by default returns the last statement it executes on the method eliminating the need to specify a return type. Let me show some more nifty features. say if i want to create a list and set in java.

List list = new ArrayList();
list.add("A");
list.add("B");
Set set = new HashSet();
set.add("A");
set.add("B");
Well with guava this can be reduced to simply these.
List list = Lists.newArrayList();
list.add("A");
list.add("B");
Set set = Sets.newHashSet();
set.add("A");
set.add("B");
With Groovy it's this simple
def list = ["A","B"]
def set = ["A","B"] as Set
I felt this was much more lucid and simple and in my integration test which is usually a lot of logic for initializing variables, helper classes, wrappers around making the calls the groovy notation reduced the number of lines of code by more than 30%. The best part was the improving the readability of the code because of the advanced workflows covering multiple scenarios. for example lets take this scenario for a method signature in both java and groovy.

public static BigInteger computeAreaOfTriangle(final long side1, 
final long side2, final long side3) {
//TODO logic to compute area using side1, side2, side3
return BigInteger.valueOf(area);
}
when this method is actually called it looks like this.
final BigInteger area = computeAreaOfTriangle(10,20,30);
Although Groovy it supports the concept of named arguments which makes it look like this.
def area = computeAreaOfTriangle(side1:10,side2:20,side3:30);
Although it looks like there is more space to represent in this notation than in the Java way but the readability it provides is much elegant and more easy to troubleshoot as well because we clearly know which argument is mapped to which parameter. That being said Groovy also did have its own pitfalls, one of them being the aspect Groovy gobbled up all the exceptions and it was very difficult to get the stacktrace of an issue as to why its actually failing. I will list this incident which actually drove me a little crazy for 20 minutes to get to the bottom of actually quite a simple issue.

//Once again blogger choking on tags for a map of Strings 
//keyed by longs.
ImmutableMap.of(1,"A",2,"B",3,"C",4,"D",5,"E",6,"F");
I used guava to create an ImmutableMap which is map of strings keyed by long values. If you were to do the step above in java, compiler would mark an Red X and complain that you can't use pass more than 5 arguments (keys and values) to the method of() it will says its an invalid argument and ask you to use the ImmutableMap.Builder for more than 5 arguments. 

 If I were to tell you on maven goals perspective. If you do maven clean verify on that code i have it will give you a compilation error immediately but with Groovy since its dynamic it was compiling the code but when it was doing the test phase it was throwing that error in the runtime and marked the test as failed on the unit test phase which confused the hell out of me until i looked at the guava javadocs for that method. 

On the overall aspect i love using Groovy and i am using that in favor of jBehave frameworks i used for integration testing previously and its making the test more sleeker in my perspective. I am also playing around a lot with Ruby and clojure as well. Hopefully by the next time i post i can make some strides onto that. (It won't be a year and half)

 Until Next time!!