Creating an Eclipse-based Groovy Development Environment for TDD
Written by Joe Rinehart, Systems Architect for Broadchoice, Inc. Posted to ArgumentCollection, the Broadchoice Engineering blog.
Last revised Wednesday, August 6, 2008.
A number of the Java components in the Broadchoice Behavioral Analytics product are built using Groovy instead of Java. The purpose of this document is to walk you through creating a Groovy development environment within Eclipse and the creation and testing of your first Groovy class.
Don't panic, it's dead-simple.
Step 1: Check Eclipse Version
You'll need at least version 3.2. I'm running 3.3.1.1. with a number of very typical plug-ins installed (Flex Builder 3, CFEclipse, XMLBuddy, WST, JBoss Tools, iLOG Elixir Charting) and the Groovy plug-in has not conflicted.
Step 2: Install the Eclipse Plug-Ins
To create our environment, we'll want to add two plug-ins. First, we'll want to install the TestNG plug-in for Eclipse. Second, we'll install the Groovy plug-in itself.
TestNG Plug-In
TestNG is a "Next Generation" testing framework for Java. Even with JUnit 4 having been released, it still offers some nice advantages (see http://www.ibm.com/developerworks/java/library/j-cq08296/). It's the preferred testing framework for use with the Groovy plug-in, so we'll need to install its plug-in.
Installation is standard, using the Eclipse update tool:
-
Select Help / Software updates / Find and Install.
-
Search for new features to install.
-
New remote site.
-
Enter http://beust.com/eclipse in the URL and whatever description you want.
-
Make sure the check box next to http://beust.com/eclipse is checked and click Next.
-
Eclipse will then guide you through the process.
Groovy Plug-In
With TestNG good to go, let's install Groovy's Eclipse plug-in. There's only so much to say about installing Eclipse plug-ins. By now, you're probably wishing I had started this paragraph with the update URL and left it at that.
One thing worth mentioning: I've only installed the Groovy and Groovy TestNG Feature, but not Grails. I'm not building Web apps with Grails right now. Install at your own peril, and if you do, YMMV on the rest of this document.
Without further ado:
Step 3: Creating a Groovy-enabled Java Project
Groovy code goes into Java projects, but there's a little configuration to do. It takes about 30 seconds once you know what to do.
-
In Eclipse, do File -> New -> Java Project. Groovy code compiles to Java. Therefore, it's just source code in a plain old Java project. I've created a project named GroovyTest and left the rest of the Java project options as their default, clicking Finish.
-
Next, I right clicked the project and did Groovy -> Add Groovy Nature. Has a nice ring to it, no? A /bin-groovy folder appears. This is where, by default, the Groovy compiler will place compiled Groovy classes. We want to use Groovy seamlessly with any Java classes we create, so we need to change this. Quoting the Groovy project's own documentation on this:
"I'm not sure why the plugin creates a bin-groovy directory. Perhaps there are other "bin" files that are best kept separate from the Groovy classes, or perhaps one of the original versions of Eclipse didn't create a "bin" directory automatically. Some day when someone has a clear idea of the usefulness of this, or lack thereof, we can clean up my instructions."
-
To ditch bin-groovy, right-click the project and select Properties. Under the Groovy Project Properties, change the "Groovy compiler output location" from "bin-groovy" to "bin" and choose "Ok" to close the dialog.
Step 4: Creating and Run a Groovy-based TestNG Test
We'll create a test before we create a Groovy class.
-
With the project all ready to get Groovy'd, let's right-click it and did New -> Source Folder to create a new source location for unit tests. For folder name, I enter "test" and click Finish.
-
Next, right-click test and do New -> Package. Create a package named "com.broadchoice.demo.groovy.test" for us to place our unit test within. We don't have to do this, but code without a package gives me the willies.
-
Right click the com.broadchoice.demo.groovy.test and do New -> Other. Expand "Groovy," choose "Groovy TestNG Class," and click Next. Name our class "CalculatorTest". Now's a good time to notice that the wizard can stub in a bunch of annotated stubs for you, such as @BeforeTest and @AfterTest. Click Finish.
-
You'll notice that the project fails to compile with an error of "unable to resolve class Test, unable to find class for annotation @...". This is because our project doesn't know about TestNG's classes - we need to add TestNG's jar to our project. There's a version of it embedded in your TestNG's plug-in, but it may be out of date. Head to http://testng.org/doc/download.html and use the "You can download TestNG here." link at the top of the page's body to download the latest TestNG .zip. Once it's unzipped, place its unzipped version wherever you keep files / libraries common to all of your projects. At Broadchoice, we maintain a /thirdparty directory in Subversion, and it's located in the BBA development branch's /thirdparty/testng. If you're a Broadchoicer, it may be easier to place it somewhere else until we merge...
-
Right-click the GroovyTest project and do Configure Build Path. For people who don't have something like our /thirdparty in an Eclipse project, use "Add External JARs..." to browse to the testng-5.8-jdk15.jar (or ...jdk14.jar if you're on a 1.4 JDK, in which case YMMV with this whole tutorial.) If your /thirdparty equivalent is in an Eclipse project, use "Add JARs..." and browse to it within the appropriate project. Maven makes things like this easier, but that's a different tutorial altogether.
-
With TestNG's jar added, we should now compile.
-
While we can ad-hoc run just our test case, it's a better idea to set up a test suite that'll run any test we place in the com.broadchoice.demo.groovy.test package.
-
Right-click the com.broadchoice.demo.groovy.test package and do New -> File and create a file named suite.xml.
-
Full documentation for what can do in here is available on TestNG's site, but for now, paste in the following XML that defines a test suite running all tests defined in the package:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="BBA Java API Tests" verbose="1" >
<test name="API Test">
<packages>
<package name="com.broadchoice.demo.groovy.test"/>
</packages>
</test>
</suite>
-
Right-click suite.xml and do Run As -> TestNG Suite. The TestNG view in Eclipse will appear, and we'll see that the testSomething() test that was stubbed passes (It does, after all, assert that true is true. If that fails, please contact your JVM provider.).
-
Let's create two tests for the fictional Calculator class we'll build in Step 5: testAdd() and testSubtract():
CalculatorTest.groovy
package com.broadchoice.demo.groovy.test
import org.testng.annotations.*
import org.testng.TestNG
import org.testng.TestListenerAdapter
import static org.testng.AssertJUnit.*;
import com.broadchoice.demo.groovy.Calculator;
public class CalculatorTest {
/**
* Main entry point to run <code>CalculatorTest</code> as
* simple Groovy class
*/
public static void main(String[] args){
def testng = new TestNG()
testng.setTestClasses(CalculatorTest)
testng.addListener(new TestListenerAdapter())
testng.run()
}
/**
* Test the add() function.
*/
@Test
final void addAccuratelyAdds(){
def calc = new Calculator()
assertTrue(calc.add(2, 3) == 5)
}
/**
* Test the subtract() function.
*/
@Test
final void subtractAccuratelySubtracts(){
def calc = new Calculator()
assertTrue(calc.subtract(2, 3) == -1)
}
}
-
We'll (obviously) not compile: we've written our test before writing Calculator.groovy, so it's ClassNotFound.
Step 5: Writing a Groovy Class
It's time to write Calculator.groovy and conclude this tutorial.
-
Right-click the src source folder and do New -> Package. Name the package com.broadchoice.demo.groovy and click Finish.
-
Right click the com.broadchoice.demo.groovy package and do New -> Other. Expand Groovy (if it's not expanded) and choose "Groovy Class" then click next. You'll notice that it's very similar to the Create a new Java Class wizard. Name the class Calculator and click Finish.
-
You can now re-run the unit test and, as expected, it will fail with a message such as:
groovy.lang.MissingMethodException: No signature of method com...Calculator.subtract() is applicable.
-
Let's write subtract:
Calculator.groovy
package com.broadchoice.demo.groovy
/**
* @author Joe Rinehart
*/
public class Calculator{
Object subtract(num1, num2)
{
return num1 - num2
}
}
-
Re-running the test should now show subtract() as passing its test but add() as still being missing. It's up to you to add it, as you've just build up a functional Groovy development environment!