savaged.info

2009-09-28

griffon waiting for the t-rex

Filed under: workfriendly — savaged @ 9:57
Tags: , , , ,

Griffon reminds me of childhood when I would collect a set of toys from inside cereal boxes. Each toy was a joy to discover. In a similar way, each Griffon feature is a thrill to see work, with as little effort as opening a cardboard box.

However, as with the Frosties collector’s set, there’s always that last piece you just can’t find. With each new box you’d open and dig down for the toy, only to find it’s not the killer toy you so desire. If Griffon were a cereal box collection of dinosaurs, GORM would be the T-Rex.

Having put together a small code-base on Grails, I really want to port the code over to Griffon without much change. Of course I would need to re-work my GSP as Griffon-style Swing. But I would prefer to stop there, with nothing else needed.

As it stands I believe I would need to alter my domain and add in a new data access layer. I know the current option for Griffon data access is fairly lightweight, certainly easier than doing it in Java. However, that’s still the sort of “boiler plate” stuff that Grails has done for me up till now.

Having read the Griffon project tenets, I expect to see GORM some time soon. Yet, after trying to track down a definitive date for when GORM integration is planned, I can’t find one.

The Groovy & Grails eXchange 2009 is just around the corner; I’m hoping that will be the cereal box with the T-Rex.

2009-09-24

groovy functional testing with gradle

Filed under: workfriendly — savaged @ 10:22
Tags: , , , , , , , ,

In my previous posting I created a ‘hello world’ style functional test example using the neat BDD framework, easyb. In that post my attention was focussed on the easyb side of things. In this post I want to draw attention to the use of Groovy when building and running the tests.

Instead of an Ant script I now can use a Groovy scripted solution. I have two choices (of course there are others); I can use Gant or Gradle. I would like to share both in that order, along with a few comments about them (please add IMHO before each comment).

Gant:

ant.path(id: 'project.classpath') {
    pathelement location: 'lib/easyb-0.9.6.jar'
    pathelement location: 'lib/commons-cli-1.2.jar'
    pathelement location: 'lib/groovy-1.6.4.jar'
    pathelement location: 'lib/selenium-java-client-driver.jar'
}

ant.taskdef(name: 'easyb', classname: 'org.easyb.ant.BehaviorRunnerTask') {
    classpath refid: 'project.classpath'
}

target(run: 'runs the tests') {
  easyb(failureProperty: 'easyb.failed') {
    classpath refid: 'project.classpath'
    report location: 'test/reports/behavior/Stories.txt', format: 'txtstory'
    behaviors(dir: '.') {
      include name: 'test/behavior/**/*Story.groovy'
    }
  }
}

setDefaultTarget run

So Gant is very much like Ant, to state the obvious, except instead of XML one can leverage the power of Groovy. I used a neat tool, called ant2gant, to help me convert my original Ant script (from the previous posting) to the version above. (I did a few tweaks, but the straight conversion would have been just as good.)

Gradle:

/**
 * needs: java -jar selenium-server.jar -interactive
 */
repositories {
    mavenCentral()
    mavenRepo urls: 'http://www.easyb.org/repoa/'
    mavenRepo urls: 'http://nexus.openqa.org/content/repositories/releases'
}

configurations {
    easybtaskdef
    easybrunner.extendsFrom easybtaskdef
}

dependencies {
    easybtaskdef(
        'org.easyb:easyb:0.9.6',
        'commons-cli:commons-cli:1.2',
        'org.codehaus.groovy:groovy-all:1.6.4'
    )
    easybrunner (
        'org.seleniumhq.selenium.client-drivers:selenium-java-client-driver:1.0.1'
    )
}

defaultTasks 'clean', 'run'

task clean << {
    new File('test/reports/behavior/Stories.txt').delete()
} 

task run << {
    ant.taskdef(
        name: 'easyb',
        classname: 'org.easyb.ant.BehaviorRunnerTask',
        classpath: configurations.easybtaskdef.asPath
    )
    ant.easyb(failureProperty: 'easyb.failed') {
	classpath {
            pathelement path: configurations.easybrunner.asPath
        }
        behaviors(dir: '.') {
            include name: 'test/behavior/**/*Story.groovy'
        }
	report location: 'test/reports/behavior/Stories.txt', format: 'txtstory'
    }
}

The Gradle version, is not too dissimilar to the Gant one, but we’re now able to use the dependency resolution Gradle offers. At a high-level view, Gradle is somewhat akin to Maven in this regard. And once again we get the advantages of using a powerful script language rather than XML.

There are enhancements I could make to my scripts, particularly to take advantage of the Groovy language. For example, I could use a variable for the easyb report, removing the repeated literal.

Here’s a small footnote for any vim folks (see my groovy minimalism posting). I found that I can get Groovy syntax highlighting in my build.gradle file simply by adding the follwing at the top.

#!groovy

Enjoy.

2009-09-14

groovy bdd with easyb

Filed under: workfriendly — savaged @ 15:42
Tags: , , , , ,

Behavioural Driven Development (BDD) is exciting to me. That’s becasue the Agile User-Story and Acceptance Criteria, actually become merged with the code-base itself. Bringing them to life, IMHO.

One framework that assists with BDD is easyb, which also has Groovy at it’s heart. Of course, I was keen to see how it could work for me. So here’s my ‘hello world’ type example:

First, I downloaded the latest version of easyb, and pop it in my home folder (or C:\). Then I knock up a simple easyb example story:

package info.savaged.testing.bdd.easyb

description 'This story is about adding'

narrative 'narrative', {
    as a 'person doing maths'
    i want 'to add two and two'
    so that 'I can find the result'
}

scenario 'add two and two', {
    given 'two is added to two', {
	total = 2 + 2
    }
    then 'the result should be four', {
	total.shouldBe 4
    }
}

And another example, this time with some Selenium thrown in:

package info.savaged.testing.bdd.easyb

import com.thoughtworks.selenium.*

description 'This story is about googling'

narrative 'this string is required for now', {
    as a 'person who uses google'
    i want 'to search for a set of internet links for a phrase'
    so that 'I can find information online'
}

before 'start selenium', {
    given 'selenium is up and running', {
        selenium = new DefaultSelenium(
            'localhost',
            4444,
            '*iexplore',
            'http://www.google.co.uk')
        selenium.start()
    }
}

scenario 'a search phrase has been entered', {
    when 'filling out the search with a phrase', {
        selenium.open '/'
        selenium.type 'q', 'savaged.info'
    }
    and 'the submit button has been clicked', {
        selenium.click 'btnG'
    }
    then 'the results should have a list of links for that phrase', {
        selenium.waitForPageToLoad '5000'
        selenium.isTextPresent 'Results * for savaged.info'
    }
}

after 'stop selenium', {
    then 'selenium should be shutdown', {
        selenium.stop()
    }
}

Finally, to make use of these behaviour files, an Ant script:

<project name="bdd" default="run" basedir=".">

    <taskdef name="easyb" classname="org.easyb.ant.BehaviorRunnerTask">
        <classpath>
	    <pathelement location="easyb-0.9.5.jar"/>
	    <pathelement location="groovy-1.6.0.jar"/>
        </classpath>
    </taskdef>

    <target name="init">
    </target>

    <target name="run" depends="init">
	<easyb failureProperty="easyb.failed">
	    <classpath>
		<pathelement location="easyb-0.9.5.jar"/>
		<pathelement location="commons-cli-1.1.jar"/>
		<pathelement location="groovy-1.6.0.jar"/>
		<pathelement location="selenium-java-client-driver.jar"/>
	    </classpath>
	    <report location="Stories.txt" format="txtstory" />
	    <behaviors dir=".">
		<include name="*Story.groovy" />
	    </behaviors>
	</easyb>
    </target>

</project>

Of course, the Ant script expects the easyb libraries and the Selenium java client jar files to be present. And you would need to have started the Selenium server remote control server running. Assuming that’s all in place running:

$ ant

Should produce some affirmative test output along with a file containing the user stories in plain text.

That’s just a silly example, but the possibilities are significant. If the business analysts or other product user in the Agile development team could work in the easyb Groovy format, the tightness of the team could be really enhanced.

IMHO, I think BDD is best compared to functional testing. I believe the User-Story and it’s test scenario(s) fits against the UI testing.

For example simple CRUD at another level of test (unit or integration), would require a fair amount of mocking. One might need to mock the http request and response, in a web-app,  for example. Whereas, coming in from the GUI, with a tool set like Selenium or Canoo Webtest, makes for clean BDD code. Especially if one were to use the before and after easyb features. After all, your manager or business sponsor should be able to see what the test is doing, and lots of ’set-up’ code would, no doubt obfuscate that.

groovy functional testing

Filed under: technology, workfriendly — savaged @ 9:58

Functional testing with Selenium now includes the ability to write one’s test case in Groovy. And the nice thing for me is that it’s remarkably easy to get going. Let me share a ‘hello world’ type example as a beginner’s guide:

Step 1

Download the latest version of Selenium RC, and extract it somewhere you can remember (eg. home on Mac or Linux, and  C:\ on MS)

Step 2

Add the Firefox Selenium IDE plugin. This step is optional, however it makes building a test case easy, because you can easily record a session. You can also see what commands are available; see how to use them, then export your test case as a Groovy file. Giving you a Groovy test case looking something like this:

package info.savaged.testing.functional

import com.thoughtworks.selenium.*

class MyTestCase extends GroovySeleneseTestCase {

    def timeout = 90000

    @Override
    void setUp() throws Exception {
        super.setUp('http://www.google.co.uk', '*iexplore')
        setDefaultTimeout(timeout)
        setCaptureScreenshotOnFailure(false)
    }

    void testMyTestCase() throws Exception {
        selenium.open '/'
        selenium.type 'q', 'savaged.info'
        selenium.click 'btnG'
        selenium.waitForPageToLoad(timeout.toString())
        assertTrue selenium.isTextPresent('Results * for savaged.info')
        selenium.click('link=savaged.info')
        selenium.waitForPageToLoad(timeout.toString())
        assertEquals 'savaged.info', selenium.getTitle()
    }
}

Step 3

Open your Groovy test case in GroovyConsole, and add the selenium jar to the classpath:

selenium-java-client-driver.jar

This can be done from the menu, in GroovyConsole:

Script->Add jar to classpath

Step 4

Run the Selenium server from the command-line, like this:

$ java -jar ~/selenium-server.jar -interactive

Step 5

Run your Groovy test case from the GroovyConsole.

2009-07-31

groovy minimalism

Filed under: technology, workfriendly — savaged @ 12:05
Tags: , , , , , , , ,

Being a minimalist, I’m not a fan of a heavy IDE, using them only when I have to. I think IDEs are like dogs, they sense your fear. At present Netbeans 6.7 seems to me to be the best trained pooch. For now however, let me propose an alternative and some background…

Recently I’ve been getting into Groovy and Grails, no doubt also appealing to my minimalist leanings. Convention over configuration let’s someone else do all the stuff that would normally clutter my development process. You have to give the tutorials a go (Groovy / Grails). If you’re a minimalist, lean processes type too, I feel sure you’ll not look back.

Now I’ve found I can mix the agility of Groovy and Grails and my favourite editor vi. At home I use Mac (did I mention I’m a minimalist). On my Mac I have MacVim. At work I’m forced to used MS Windows, I have CygWin and include vim from the setup tool.

Of course, I could have used TextMate on my Mac, and at work, the clone for MS “e“. However, I’m also a minimalist when it comes to paying money out (aka: being tight).

There are a few hoops to jump through to get going; I wanted to share them with all the other minimalists.

Step 1

Get a vimrc file working. See http://macvim.org/OSX/index.php. Particularly note the instructions about getting the $VIMRUNTIME/vimrc_example.vim files. (Works on MS Windows too, and probably Linux).

Step 2

Get Groovy language highlighting. Download groovy.vim. You might need to create a .vim directory in your home, and a ftplugin directory in there. Once you have that you just drop the groovy.vim file into ftplugin (works for both Mac and MS).

Step 3

Add NERDTree. Download and unzip NERD_tree.zip. Put the NERD_tree.vim file into your ./vim/plugin directory and NERD_tree.txt into your .vim/doc directory. (Note that you might need to create plugin and doc directories, if it’s your first plugin).

Step 4

Add snipMate. Download and unzip snipMate.zip into your ./vim/plugin and doc directories; as you did above.

Step 5

In vim run :helptags ~/.vim/doc then :help local-additions to view the docs for both the plugins.

Step 6

In vim run something like :NERDTree /mycode/mygroovyproj/

Step 7

Revel in the simplicity of your new development environment ;)

Finally, when you really do need an IDE then there’s great Groovy & Grails support in Netbeans and now in Eclipse. Oh and the one you have to pay for, Intellij.

2009-06-8

gradually groovy

Filed under: technology, workfriendly — savaged @ 13:19
Tags: , , , , , ,

This week I’ve been mostly reading Programming Groovy – Dynamic Productivity for the Java Developer by Venkat Subramaniam. This is one of those few books where you don’t skim or skip forward, where the author(s) keeps you engaged end to end.  The subject could also be a contributing factor; Groovy is quite something. There are a number of “wow” moments as you go through the book, seeing practical ways you might truly enhance your productivity.

I’m a firm believer in ‘convention over configuration‘. Groovy takes all the ceremony, repeated by each and every Java programmer every time, and does it for you. Leaving you to get on with lines of code that concentrate on delivering business value.

As I say there are many “wow” moments learning Groovy, however there’s one that stands out to me as a Product Owner, namely the ease of integration. What this means to me is a team could choose to move gradually to Groovy. The project unit tests could be used to provide the security to refactor Java functionality over to Groovy bit by bit. A steady progression rather than a big re-write. The Java and the Groovy living side by side over a period of time. I think Groovy stands out from the other similar languages, in this regard.

(Thanks Darran for pointing me in the Groovy direction)

Next stop Grails.

2009-06-1

tinkering with the google maps api

Filed under: Google Maps, software — savaged @ 14:31
Tags: ,

I’ve been tinkering around with the Google Maps API today. I’m looking for a way to show map boundaries and then have a user search for them. Kind of a ‘find my nearest’, but with zones rather than locations. I’ve put together the following code* which should demonstrate some of the features that I might leverage. I thought I’d post it here, in case anyone is looking for something similar.

* Lifted from other examples already on the web

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Google Maps JavaScript API Example: Simple Polygon</title>
    <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;
key=ABQIAAAAzr2EBOXUKnm_jVnk0OJI7xSosDVG8KKPE1-m51RBrvYughuyMxQ-i1QfUnH94QxWIa6N4U6MouMmBA"
            type="text/javascript"></script>
    <script type="text/javascript"> 

    var label, centre, point;

    function initialize() {
	    if (!GBrowserIsCompatible()) {
	    	alert("Your browser is not compatible, sorry");
	    	return;
    	}

    	var map = new GMap2(document.getElementById("map_canvas"));

        centre = new GLatLng(51.614259,-0.212967);
        map.setCenter(centre, 16);

        var polygon = new GPolygon([
        new GLatLng(51.613886,-0.214105),
        new GLatLng(51.614699,-0.214105),
        new GLatLng(51.614619,-0.212023),
        new GLatLng(51.613820,-0.211916),
        new GLatLng(51.613886,-0.214105)
        ], "#f33f00", 5, 1, "#ff0000", 0.2);

        map.addOverlay(polygon);

        label = new GMarker(centre);

        map.addOverlay(label);
        label.openInfoWindow("My Zone");
    }

	function showLocation() {
		label.hide();
		var geocoder = new GClientGeocoder();
		geocoder.getLocations(document.forms[0].address1.value, showLocationCallback);
	}

	function showLocationCallback(response)  {
		if (!response || response.Status.code != 200) {
			alert("Sorry, we were unable to geocode the address");
		}
		else {
			place = response.Placemark[0];
			point = new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]);
			calculateDistance();
		}
	}

	function calculateDistance() {
		try {
			var metresdistance = centre.distanceFrom(point);
			var milesdistance = Math.round(metresdistance * 0.000621371192237334);
			label.openInfoWindow("<p>My Zone</p> <p>Distance: "   milesdistance   " miles.</p>");
		}
		catch (error) {
			alert(error);
		}
	}

    </script>
  </head>
  <body onload="initialize()" onunload="GUnload()">
    <div id="map_canvas" style="width: 500px; height: 300px"></div>
    <form action="#" onsubmit="showLocation(); return false;" ID="Form1">
		<p>
			<input type="text" name="address1" value="Pratt Mews, NW1"
				class="address_input" size="40" ID="Text1" />
			<input type="submit" name="find" value="Find Distance" ID="Submit1" />
		</p>
	</form>
  </body>
</html>

2009-03-19

The 21st Century Where’s Wally?

Filed under: workfriendly — savaged @ 12:26
Tags: ,

As Google Streetview comes to life in London, I rushed to see if I could find myself. It’s about six months ago, or more, since I saw the Google Beatle Car pass me. Perhaps it’s a measure of my ego that I remembered that and that it was the first thing I looked for; ah well.

Here I am, the guy in the suit; really ;)

2009-03-5

why so little noise for wine on mac osx

Filed under: technology — savaged @ 16:36
Tags: , , , , , , , , ,

It’s a strange thing to me that there’s not a lot more noise on the web about Wine on Mac OS X. The Darwine project seems to me to have dust and cobwebs on it. If there is work going on getting Wine packaged and supported on Mac as it is on Linux, it’s not very transparent to a keen user like myself.

I found just one such “project” here, however that too looks quiet, plus it looks like one individual who has put the work in rather than a community of collaborators. The word on the web seems to be DIY.

There is of course the Cross-Over crew, however, this is not FOSS. And more importantly, while very very good, that platform mostly caters for “main stream” MS based apps.

The motivation to get Wine working on Mac can often be quite specific, perhaps because of a very proprietary piece of software. That is certainly, my case where I have everything I need on the Mac, for example a full office suite. Everything, that is, bar just one thing. I was very pleased to hear one more enthusiastic individual has taken it upon himself to create a bespoke package, this time specifically for that one application.

However, I’m still puzzled as to why there’s no community of Mac users as there is for Linux. Sure there’s the dual boot option, but that requires a Windows license which comes with a temptation to be a pirate. Or there’s dual booting to Linux, but that’s tricky or at least a bit of an overkill, when all you need is one app running on your macbook.

Perhaps there’s so little interest because the number of important proprietary applications are now few and on the decline. More and more apps are either cross-platform or fully web-based these days. Being platform dependant may become even more important as devices like the iPhone and netbooks are favoured over the PC. Also with the cost of producing and distributing installation media increasing, no doubt will promote web-based applications. The Google pack of tools is a good example of this trend, as is one of my favourites, the Remember The Milk task list.

So perhaps Darwine is unlikely to get any traction. And on that basis there’s a possibility Wine itself may become obsolete.

2009-02-12

a humbling experience

Filed under: General — savaged @ 14:27
Tags: , ,

I’m starting to learn German from a total zero starting point. This is already a very humbling experience. I keep thinking how similar it is to being a toddler once more. I’m getting a set of lessons from a tutor and I’ll also be using a CD course from Michel Thomas. Anyway here are a few sentences that I’m aiming to use in these early days of learning the very very basics.

Ich weiß nicht. I don’t know.
Bitte noch einmal. Again please.
Ich verstehe nicht. I don’t understand.
Entschuldigung, sprechen Sie langsamer. Sorry, please say that slowly.
Wie heißt das auf Deutsch? What does it mean in English?
Buchstabieren Sie bitte. Spell it please.
Wie schreibt man das? How do you write that?

And perhaps most useful:

Hilfe!                        Help!

There is one tech thing that struck me in one of my early lessons. It was when I was learning to count. The German for zero is “null”. That strikes me a quite problematic. If I talk to a German colleague and say “null” he might easily think I’m saying “0″! Of course null and zero are quite different and mixing the two could cause some very hard-to-find bugs in code. I wonder if this is a common problem, with IT teams that span the English and German languages.

Next Page »

Blog at WordPress.com.