implements Elegance {

// Elwyn Malethan's musings on software development, mountain biking and general navel–gazing...

Ruby has Rspec. Where's Jspec?

In my new job I am almost exclusively working with Java. Not only that, I‘m working as part of an established team, so I‘m working to their conventions and processes. So I‘m not working with the same variety of technologies as I am used to.

Having been away from Ruby land for a couple of weeks it‘s made me think about how practitioners of Ruby and those of Java differ in approach. Now, I‘m not saying for a second you have to exclusively be one camp or the other. Neither am I saying that being a Java developer somehow defines the way you think, likewise for Ruby.

However, in Ruby land you hear words like elegant , beautiful and expressive as being considered virtuous adjectives to describe solutions or source code. You don‘t hear those words half as often in Java land, it‘s a little more ruthless and business-like. There‘s a little less magic.

This got me thinking. One of my favourite Ruby frameworks is Rspec. What if someone had tried to implement a testing framework in Java using some of the ideals that the developers of Rspec employed? One of the reasons I like Rspec is it‘s sheer expressiveness. That and the fact it actually generates documentation that a non-developer could read and QA the solution against (well, if the specs are well written anyway).

Jspec?

Jspec is the fictional Java implementation of Rspec. I'm not sure if there is already a Jspec but it‘s as good a name as any to describe the fictional framework I‘m about to introduce.

Anyway what would Jspec look like? How does the Java syntax and idioms allow us to implement such a framework in the most expressive, elegant and beautiful way? Firstly let‘s look at what our test might look like using rspec to test MyWidget.

JHighlight doesn't support Ruby, so the syntax highlighting isn't great.

Pure english descriptions of our tests
describe "My Widget in some scenario" do
    before(:all) do
        # Some bootstrapping
    end

    before(:each) do
        # Some initilaisation of info
        @my_widget = MyWidget.new
    end

    describe "Given some conditions" do

        it "should satisfy some criteria" do
            @my_widget.perform_functionality

            @my_widget.result.should == "Hello World!"
        end

        it "should produce some specified results" do
            # Some testing
        end
    end
end

References the class directly
describe MyWidget, "Given in a different scenario" do
    it "should satisfy some condition we apply" # Results in a warning about a pending test
end

This doesn‘t look much like your average Ruby program. It looks like a DSL that someone came up with to describe tests in an elegant way. But it‘s not a DSL, it is perfectly valid Ruby code. Ruby has the syntactic flexibility to allow such elegant and expressive solutions. Some might even say that it is beautiful. It also has the feature of blocks and/or closures, which are unnamed blocks of code or functions that can be passed around. They‘re the biggest reason Rspec is the way it is.

Well, Java doesn‘t have unnamed functions or the ability to pass blocks of code about, well not yet anyway. The nearest thing Java has at the moment is Anonymous Classes.

Jspec using Anonymous Classes

Below is what Jspec might look like if it was implemented in today‘s Java, using Anonymous Classes. I hasten to add that I haven't implemented any of this beyond code stubs. This is just theoretical.

package com.malethan.jspec;

import static com.malethan.jspec.Jspec.*;
import com.malethan.jspec.annotations.Spec;
import com.malethan.jspec.annotations.Before;


class MyWidgetSpec {
    MyWidget thing;

    @Spec   //to mark this method as a runnable spec
    public void test() {

        describe(new Example("My Widget in some scenario") {

            @Before(ALL)
            public void setup() { /* ... */ }

            /**
             * Runs before each Should block
             */
            @Before(EACH)
            public void beforeEach() {
                thing = new MyWidget();
            }

            public void run() {
                describe(new Example("Given some conditions") {
                    public void run() {
                        itShould(new Satisfy("a given criteria or condition") {
                            public void run() {

                                thing.performFunctionality();

                                specify(thing).getResult(); should(eq("Hello World!"));
                            }
                        });

                        itShould(new Satisfy("should produce some specified results") {
                            public void run() {
                                // Some testing
                            }
                        });
                    }
                });
            }
        });

        //References the class directly
        describe(new Example(MyWidget.class, "Given in a different scenario") {
            public void run() {
                itShould(new Satisfy("should satisfy some condition we apply")); //Results in a warning about a pending test
            }
        });

    }
}

A word of explanation: The methods describe, itShould and specify are all static methods on the Jspec class. Similarly ALL and EACH are both static properties on Jspec, though these could be replaced by a separate enum perhaps. Example extends an abstract class that requires it implement the run() method. The class Satisfy extends a class that has a default implementation or run() that generates a warning (or it would if I had actually implemented any of this).

Whilst the code above satisfies expressiveness – to the extent one can using the Java syntax – it's not really that elegant and it certainly isn't beautiful. There is also far too many parentheses cluttering up the code. My conclusion is I should stick to JUnit or TestNG for the time being.

However, what might Java have in store for us in future and will this allow us more elegant, beautiful solutions? Closures might be available to us in the next release of Java. This is what Jspec might look like implemented using Java 1.7.

package com.malethan.jspec;

import static com.malethan.jspec.Jspec.*;
import com.malethan.jspec.annotations.Spec;


class MyWidgetSpec {
    MyWidget thing;

    @Spec   //to mark this method as a runnable spec
    public void test() {

        describe("My Widget in some scenario", {

            before(ALL, { /* ... */ });

            /**
             * Runs before each Should block
             */
            before(EACH, {
                thing = new MyWidget();
            });

            describe("Given some conditions", {
                it("should satisfy a given criteria or condition", {
                    thing.performFunctionality();

                    //Like how jMock does expectations in 2.x API
                    specify(thing).getResult(); should(eq("Hello World!"));
                });

                it("should produce some specified results", {
                        // Some testing
                });
            });
        });

        //References the class directly
        describe(MyWidget.class, "Given in a different scenario", {
            it("should satisfy some condition we apply"); //Results in a warning about a pending test
        });

    }
}

Voila! Definitely expressive – at least as much as Ruby. Arguably elegant and I think it could almost be considered beautiful. In fact the solution using closures is so like Rspec I wouldn‘t be surprised if someone is working on a port of it to Java 1.7 already. That is of course if the closures idea is going to be included in the next release of Java.

If someone is working on a port of Rspec, I‘d love to hear about it. Also, let‘s hope closures make it into Java 1.7.

First published on Dec 13, 2008. Last updated on: Jan 26, 2009.

Comments (3)

Leave a reply »

 
 

Hello there,

It looks quite interesting. Is anyone implementing a JSpec? I would be happy to help.

Bye,

David

 

... nd given that I even navel–gazed about a possible Java implementation of Rspec‘s specs, I was shocked to find that a href=”http://www.e …

 

Hey ! I happen to have coded something that looks like what you describe. You can visit the project‘s page here :
http://typo.hypomnema.net/2010/02/18/jfunctest-a-small-functional-testing-framework

and also get it from github :
http://github.com/subtenante/jfunctest

Please share thoughts !

Leave a Reply

Your name
 
Email
 
Website
 
Comment

You may use Textile notation here
 
 

Please perform this simple arithmetic test to prove you are human
 
 
 
People I like
Other sites