Pomodoro, AppleScript and Adium

I downloaded this Pomodoro Timer from the Apple website.
It has support for AppleScript events, so I created a script that automatically sets my Adium status to away (with an auto-reply) while I am working on a Pomodoro and automatically sets it to Available when I have finished.

After much messing around, trying to work out just how the AppleScript pseudo-natural-language works, I ended up with this to set the away status:

-- This goes on one line in Pomodoro Setup -> AppleScript -> Start
tell application "Adium"
  to set the status of every account whose status type is available
  to the first status whose title is "Pomodoro In Progress"

and this to set it back to available:

-- This goes on one line in Pomodoro Setup -> AppleScript -> Reset and End
tell application "Adium"
  to set the status of every account whose status type is away
  to the first status whose title is "Available"

Tiny Types

Mark Needham’s post on micro types sparked an idea in my head that recently came to fruition.
I was pondering on the Narrative Fixture code, and the fact that, although most of the internals are sensibly typed objects, at the FitNesse layer, we do a lot of passing of strings.
The idea (at least, my interpretation) with Tiny Types is that the string obviously means something, and that we can probably classify what that meaning is (we have a sensibly named variable for it, after all) , and so why not convert it to that meaningful thing as soon as possible.
This has the nice effect of making some vague things (such as typing on collections) much more explicit.

As an example, in the Casting Director we have:

Map<String, ActorPlayingThe<?>> dressingRoom = new HashMap<String, ActorPlayingThe<?>>();

and, after a little bit of refactoring, we end up with:

Map<CharacterName, ActorPlayingThe<?>> dressingRoom = new HashMap<CharacterName, ActorPlayingThe<?>>();

Personally, I’m a fan of low ceremony, high essence languages, but while working in a high ceremony environment, we can leverage that ceremony to provide us with a nice summary of our thinking, ready for the next time we return to the code.

Lazynchronous

la⋅zyn⋅chro⋅nous /ˈleɪzɪŋkrənəs/

–adjective

  1. having delegated a task with a desired output to a person or group of persons
Examples:

  • Asking your colleague / friend / network a question, where you could find the answer by using a popular search engine, would be a lazynchronous search.
  • Getting Mechanical Turk to transcribe your screencasts allows you to work lazynchronously.
Origins:
Compound, from virtue of laziness and asynchronous

Making Feedback More Effective

Patrick Kua recently wrote a Guide for Receiving Feedback. He mentions that one way to understand how to receive feedback is to understand how to give it.

Here are some suggestions for giving feedback that will help to anchor desirable behaviours and enable change in less desirable behaviours.

Give feedback in the second person

One purpose of feedback is to keep desirable behaviours and to change less desirable behaviours in the person you are feeding back on. Who is the correct audience for this information? Is it the manager of that person?
Using the third person isolates you from the person, and can encourage the use of generalisations.

Consider:

Gina worked very hard on this project. She always seemed to be at her desk long after everyone else had gone home.

versus:

Gina, you are very dedicated. I remember, one Friday, I got home and realised that I had left my keys on my desk. When I came back to the office to get them, you were still there. It must have been half past eight.

Which feedback would have the most effect on you? Why?

Anchor desirable behaviours in the present

When you are giving feedback on desirable behaviours, use the present tense. Specific examples can be given in the past tense.
For example:

David gave a great presentation to the board. The audience loved it and gave him a round of applause

David gave a great presentation? Was it a fluke? Can he do it again?

Consider this alternative:

David is a great communicator. His presentation to the board captivated the audience for the entire hour, and received a spontaneous round of applause.

David is a great communicator. The fact that he is implies that he will continue to be a great communicator.

Address it to David:

David, you are a great communicator. The presentation you gave to the board was amazing, the audience was captivated. You really deserved that round of applause.

Which feedback would have the most effect on you? Why?

Anchor less desirable behaviours in the past, suggest alternative behaviours

Giving feedback about undesirable behaviours is difficult. We want to get the message across without appearing to be overly cruel or negative.

Geoff thinks that he’s the only one who knows what’s going on. He always tells people how to do their jobs

How does the person giving the feedback know what Geoff thinks? Does Geoff always tell people how to do their jobs? How do you think that Geoff will respond to this feedback?

Give specific, past examples of the behaviour, suggest a way forward:

Last week, Geoff asked me to do the monthly report, and then told me how to do it. I felt as though he was questioning my competence. If Geoff wants me to do the report, he only needs to ask me.

How will Geoff react to this one?

Address it to Geoff:

Geoff, last week you asked me to do the monthly report, and then you told me how to do it. This upset me, as it felt like you were questioning my competence. I’m happy to do the report, you only need to ask me.

Which feedback do you think would have the most effect on the way Geoff interacts with the person giving the feedback?

Feedback on this post is valued and encouraged


My current understanding of feedback was gained from my interactions with other great coaches, including Liz Keogh, Antony Marcano, Rachel Davies and more.
A special mention goes to Chris Pollard for really opening my eyes to the value of language and well-formedness when giving feedback to elicit change.

Showing FitNesse Test Results in Hudson

Have you tried to get your FitNesse reports into Hudson?

Although it’s simple to get an Ant task to run the tests, and fail the build, it would be nice to see the results in Hudson’s junit report.
Unfortunately FitNesse outputs it’s results in a format that Hudson doesn’t understand. But that’s OK, because it’s all XML.

I knocked together a really quick Proof of Concept xsl and ant script that allow you to run the FitNesse tests and convert the output to the Ant junit format that Hudson understands.

It’s a work in progress, but it should be enough to get you going. Watch this space.
I ran it against one suite and Hudson picked up the tests (and failure) ok.

This is the build.xml that I found on Naresh Jain’s blog about integrating FitNesse with CruiseControl, with the convert target added

<?xml version="1.0" encoding="UTF-8"?>
<project name="Acceptance_Tests-Common" default="test">
  <target name="smoke" description="Run fitnesse acceptance tests.">
    <property name="fitnesse.output.dir" value="build" />
    <property name="fitnesse.output.file" value="${fitnesse.output.dir}/fitnesse-test-results" />
    <property name="fitnesse.port" value="8765" />
    <path id="fitpath">
      <fileset dir=".">
        <include name="fit*.jar" />
        <include name="lib/fitnesse-20070619/fitnesse-20070619.jar" />
      </fileset>
    </path>
    <echo message="About to run fitnesse server" level="info" />
    <parallel>
      <daemons>
        <java classname="fitnesse.FitNesse" classpath="${toString:fitpath};${ant.home}/lib/xercesImpl.jar">
          <arg value="-p" />
          <arg value="${fitnesse.port}" />
          <arg value="-e" />
          <arg value="0" />
          <arg value="-d" />
          <arg value="content" />
          <arg value="-r" />
          <arg value="FitnesseRoot" />
        </java>
      </daemons>
      <sequential>
        <echo message="sleeping for 10 seconds to let FitNesse server start" level="info" />
        <sleep seconds="10" />
        <java classpathref="fitpath" classname="fitnesse.runner.TestRunner" fork="true" resultproperty="fit.test.failures">
          <arg value="-debug" />
          <arg value="-xml" />
          <arg value="${fitnesse.output.file}.xml" />
          <arg value="-html" />
          <arg value="${fitnesse.output.file}.html" />
          <arg value="localhost" />
          <arg value="${fitnesse.port}" />
          <arg value="UserStories.FooterStory" />
        </java>
        <replace file="${fitnesse.output.file}.html" token="<base href="http://localhost:${fitnesse.port}/"/>" />
        <echo message="Finished FIT tests: ${fit.test.failures} failures/exceptions" level="info" />
        <!--
	  <fail message="FIT test failures/exceptions: ${fit.test.failures}">
	    <condition>
	      <not>
	        <equals arg1="${fit.test.failures}" arg2="0" />
	      </not>
            </condition>
	  </fail>
	  -->
      </sequential>
    </parallel>
  </target>

  <target name="convert-fitnesse-results-to-junit">
    <xslt style="fitnesse2junit.xsl" in="build/fitnesse-test-results.xml" out="build/TEST-fitnesse.xml" />
  </target>

  <target name="test" depends="smoke, convert-fitnesse-results-to-junit" />
</project>

A slight update on the XSL. This one creates the correct nodes for exceptions and errors (although it appears to make no difference to Hudson)

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <xsl:element name="testsuite">
    <xsl:attribute name="tests">
      <xsl:value-of select="sum(testResults/finalCounts/*)" />
    </xsl:attribute>
    <xsl:attribute name="failures">
      <xsl:value-of select="testResults/finalCounts/wrong" />
    </xsl:attribute>
    <xsl:attribute name="disabled">
      <xsl:value-of select="testResults/finalCounts/ignores" />
    </xsl:attribute>
    <xsl:attribute name="errors">
      <xsl:value-of select="testResults/finalCounts/exceptions" />
    </xsl:attribute>
    <xsl:attribute name="name">AcceptanceTests</xsl:attribute>
  <xsl:for-each select="testResults/result">
    <xsl:element name="testcase">
      <xsl:attribute name="classname">
        <xsl:value-of select="/testResults/rootPath" />
      </xsl:attribute>
      <xsl:attribute name="name">
        <xsl:value-of select="relativePageName" />
      </xsl:attribute>
      <xsl:choose>
        <xsl:when test="counts/exceptions > 0">
          <xsl:element name="error">
            <xsl:attribute name="message">
              <xsl:value-of select="counts/exceptions" />
              <xsl:text> exceptions thrown</xsl:text>
              <xsl:if test="counts/wrong > 0">
                <xsl:text> and </xsl:text>
                <xsl:value-of select="counts/wrong" />
                <xsl:text> assertions failed</xsl:text>
              </xsl:if>
            </xsl:attribute>
          </xsl:element>
        </xsl:when>
        <xsl:when test="counts/wrong > 0">
          <xsl:element name="failure">
            <xsl:attribute name="message">
              <xsl:value-of select="counts/wrong" />
              <xsl:text> assertions failed</xsl:text>
            </xsl:attribute>
          </xsl:element>
        </xsl:when>
      </xsl:choose>
    </xsl:element>
  </xsl:for-each>
  </xsl:element>
</xsl:template>
</xsl:stylesheet>

Eclipse Workspace Template

Following on from my Installing Eclipse post, I put together an empty workspace using my recommendations, as well as a couple from the Ivan Moore and Mike Hill session Programming in the Small.

Unzip the template into your workspaces directory and rename it to whatever you want your new workspace to be called. When you start Eclipse, browse to the new workspace directory and have all your code templates set up already.

Download the Eclipse Workspace Template

Please feel free to make suggestions for further improvement.

Do you have enough oil?

I was talking to someone who had had a project manager mention in a retrospective that he felt that the testing was slowing down the delivery. They wanted to stop “wasting time” on testing and refactoring.
When I heard this, I said “That’s a bit like going on a car journey and your passenger telling you to ignore the oil pressure light because they don’t want you wasting time topping up the engine oil”

Admittedly, you will get underway faster, but that’s going to be very little comfort when you come to a grinding halt a few miles down the road.

Code should start out messy

Earlier today Antony said on Twitter:
“stop apologising if your code starts out messy… it’s how it ends up that counts…. you can’t make an omelette without breaking some eggs”

I replied:
“Code _should_ start out messy. Finding the right places for things is harder when they’re already neatly in the wrong place”

If you have a preconceived idea of where your code should go, you will put it there by default. Antony told me an experience he had with this when he was untangling dependencies in jnarrate. By moving everything into a single package, then repackaging based on affinity, a much better package structure revealed itself.

At home, I would really like to re-organise my kitchen so that the pans are closer to the cooker. It makes sense from an ergonomics point of view. However, they already have a home. In order to rearrange the pans, I would have to empty the existing cupboard and the destination cupboard. It’s less work for me to put the pans back in their existing space, but it bothers me whenever I think of it. I really should fix that

Installing Eclipse

I’ve just bought myself a netbook, and following the example set by John Smart with his article on installing Eclipse, I’ll document what I do with a clean install of Eclipse.

First Things First

I download the Eclipse IDE for Java Developers. The download is less than half the size of the Java EE edition, and I can always add the extra plugins later (if needed)

Plug it in

I install the mercurial plugin. There is a pattern that I use for pushing mercurial changes to other SCMs (eg. subversion) that I will describe in another post. I intend to use Ivy for my dependency management, so I install IvyDE. I then install the code quality plugins that John mentions, as well as the Metrics plugin. (the following links are the urls for the update sites)

I also install JUnitMax. This is a new plugin from Kent Beck that runs your unit tests after every save. It’s currently on paid beta, and I highly recommend it. Subscribe here, it’s only $2/month

Templates

I update the following templates in Java -> Code Style -> Code Templates

Method Body

// ${todo} Auto-generated method stub
${body_statement}

This evaluates to an empty (apart from the comment) method for void types, or return null;. I’ve already discussed my thoughts on returning null, and I would rather my code failed if it hits an unimplemented method rather than continue in a potentially unsafe manner. So, I change this to:

throw new UnsupportedOperationException("TODO: Implement this method");

Catch block body

// ${todo} Auto-generated catch block
${exception_var}.printStackTrace();

I’ve also discussed my thoughts on checked exceptions. I prefer to not silently hide the exception with a stack trace, I also don’t want to make my callers deal with checked exceptions, so I change this template to:

throw new RuntimeException("TODO: Handle this exception better", ${exception_var});

Test Templates

I also create a new test template in Java -> Editor -> Templates. I copy the Test method (JUnit 4) and add some Behaviour Driven Design style guiding comments. Because I’m lazy, I name it T :-)

@${testType:newType(org.junit.Test)}
public void should${DoSomething}() throws Exception {
  // Given
  ${cursor}
  // When
  // Then
}

Favourite Imports

I add the following classes to Java -> Editor -> Content Assist -> Favorites so that I can get type completion on my favourite static imports

  • org.hamcrest.CoreMatchers.*
  • org.hamcrest.Matchers.*
  • org.junit.Assert.*
  • org.mockito.Mockito.*

Code formatting

These are the changes I make to the default Eclipse settings for my personal code.
In Java -> Code Style -> Formatter

Indentation -> General Settings -> Tab Policy => Spaces only
Indentation -> General Settings -> Indentation size => 2
Indentation -> Indent -> Statements within 'switch' body => on
Control Statements -> General -> Insert new line before 'else' in an 'if' statement => on
Control Statements -> General -> Insert new line before 'catch' in a 'try' statement => on
Control Statements -> General -> Insert new line before 'finally' in a 'try' statement => on
Control Statements -> 'if else' -> Keep 'return' or 'throw' clause on one line => on
Line wrapping -> Line width and indentation levels -> Maximum line width => 132

I also make the following changes to the compiler warning settings (Java -> Compiler -> Errors / Warnings)

Potential Programming Problems -> Serializable class without serialVersionUID => Ignore
Unnecessary Code -> Unused Import => Error

Happy New Year

It’s a new year, and I thought I would write down some of my goals for the next twelve months.