Author Archive for paul

Mock objects on Android with Borachio: Part 1

For a complete worked example of using Borachio on Android with RoboGuice for Dependency Injection, go here

One of my biggest frustrations with writing code for Android has been the fact that none of the current Java mocking frameworks work on Android’s Dalvik VM. I recently released Borachio a native Scala mocking framework which does work on Android.

Because Borachio is written in Scala, you’ll need to write your tests in Scala. But it can be used to test code written in Java.

This post demonstrates how to get basic mocking working. Things get more complicated when you try to mock bits of Android itself, but I’ll cover that in a subsequent article.

This is an Android version of the example in Martin Fowler’s article Mocks Aren’t Stubs. The code is checked into GitHub here. You’ll need to have the Android SDK and Scala 2.8 installed to run this code.

We’re going to build a (very) simple ordering system. Orders will succeed if there’s enough inventory in our warehouse and fail if not. Let’s start by creating a very simple little Android application for us to test:

  1. Create a new project with:

    android create project -p WarehouseManager -t android-8 \
        -p warehousemanager -k com.example.warehousemanager \
        -a WarehouseManager
  2. The core abstraction is a warehouse, represented by a Warehouse interface:

    package com.example.warehousemanager;
     
    public interface Warehouse {
        boolean hasInventory(String product, int quantity);
        void remove(String product, int quantity);
    }
  3. And here’s a very simple concrete implementation of Warehouse:

    package com.example.warehousemanager;
     
    import java.util.HashMap;
     
    public class RealWarehouse implements Warehouse {
        public RealWarehouse() {
            products = new HashMap<String, Integer>();
            products.put("Talisker", 5);
            products.put("Lagavulin", 2);
        }
     
        public boolean hasInventory(String product, int quantity) {
            return inStock(product) >= quantity;
        }
     
        public void remove(String product, int quantity) {
            products.put(product, inStock(product) - quantity);
        }
     
        private int inStock(String product) {
            Integer quantity = products.get(product);
            return quantity == null ? 0 : quantity;
        }
     
        private HashMap<String, Integer> products;
    }
  4. We remove things from the warehouse by placing an Order:

    package com.example.warehousemanager;
     
    public class Order {
     
        public Order(String product, int quantity) {
            this.product = product;
            this.quantity = quantity;
        }
     
        public void fill(Warehouse warehouse) {
            if (warehouse.hasInventory(product, quantity)) {
                warehouse.remove(product, quantity);
                filled = true;
            }
        }
     
        public boolean isFilled() {
            return filled;
        }
     
        private boolean filled = false;
        private String product;
        private int quantity;
    }
  5. We’ll need a UI to allow us to make orders, so modify main.xml to look like this:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
      <TextView  
          android:layout_width="fill_parent" 
          android:layout_height="wrap_content" 
          android:text="Product:"
          />
      <EditText
          android:layout_width="fill_parent" 
          android:layout_height="wrap_content"
          android:id="@+id/product"
          />
      <TextView
          android:layout_width="fill_parent" 
          android:layout_height="wrap_content" 
          android:text="Quantity:"
          />
      <EditText
          android:layout_width="fill_parent" 
          android:layout_height="wrap_content"
          android:id="@+id/quantity"
          />
      <Button
          android:layout_height="wrap_content"
          android:layout_width="wrap_content"
          android:text="Place order"
          android:onClick="placeOrder" />
    </LinearLayout>
  6. And finally, here’s the implementation of WarehouseManager:

    package com.example.warehousemanager;
     
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.Toast;
     
    public class WarehouseManager extends Activity
    {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
     
            productEditText = (EditText)findViewById(R.id.product);
            quantityEditText = (EditText)findViewById(R.id.quantity);
        }
     
        public void placeOrder(View view) {
            String product = productEditText.getText().toString();
            int quantity = Integer.parseInt(quantityEditText.getText().toString());
            Order order = new Order(product, quantity);
            order.fill(warehouse);
     
            String message = order.isFilled() ? "Success" : "Failure";
            Toast toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
            toast.show();    
        }
     
        private Warehouse warehouse = new RealWarehouse();
     
        private EditText productEditText;
        private EditText quantityEditText;
    }

You should now have a little Android application that can be compiled and installed with ant install. Here’s what it looks like:

Screenshot

So, now that we’ve got something to test, let’s create a test project to test it:

  1. Create a test project with:

    android create test-project -p test -m .. -n WarehouseManagerTest

    Next, we’ll convert this to a Scala project, as described here.

  2. Add scala.dir and proguard.dir to local.properties. Here’s what I added to mine (you’ll need to change the paths to match your local installation):

    scala.dir=/opt/local/share/scala-2.8
    proguard.dir=/Users/paul/android-sdk-mac_86/tools/proguard/
  3. Copy build-scala.xml into the root of the test project and add the following to build.xml:

    <import file="build-scala.xml" />
     
    <!-- Converts this project's .class files into .dex files -->
    <target name="-dex" depends="compile, scala-compile, scala-shrink">
        <scala-dex-helper />
    </target>
  4. Delete the proguard.cfg file and copy the configs directory into the test project. Add the following to the bottom of both default-debug.cfg and default-release.cfg (to ensure that ProGuard doesn’t discard our test classes:

    -keep public class * implements junit.framework.Test { public void test*(); }
  5. Copy the Borachio JAR to the libs directory.
  6. Finally, we can write our tests, which create mock instances of the Warehouse interface:

    package com.example.warehousemanager;
     
    import junit.framework.TestCase
    import com.borachio.junit3.MockFactory
     
    class OrderTest extends TestCase with MockFactory {
     
      def testInStock() {
        withExpectations {
          val mockWarehouse = mock[Warehouse]
          inSequence {
            mockWarehouse expects 'hasInventory withArguments ("Talisker", 50) returning true once;
            mockWarehouse expects 'remove withArguments ("Talisker", 50) once
          }
     
          val order = new Order("Talisker", 50)
          order.fill(mockWarehouse)
     
          assert(order.isFilled)
        }
      }
     
      def testOutOfStock() {
        withExpectations {
          val mockWarehouse = mock[Warehouse]
          mockWarehouse expects 'hasInventory returns false once
     
          val order = new Order("Talisker", 50)
          order.fill(mockWarehouse)
     
          assert(!order.isFilled)
        }
      }
    }
  7. Run the tests with:

    ant run-tests

In part 2, we’ll look at some of the challenges of mocking Android components.

Updated 2011-04-15

Updated to Borachio 0.6.

Mocking in Scala with Borachio step-by-step

Borachio is now ScalaMock.

Recently, I announced Borachio, native mocking for Scala. This post is a full worked example of using Borachio with ScalaTest and sbt.

The example assumes that we’re writing code to control a mechanical turtle, similar to that used by Logo programs. Mocking is useful in this kind of situation because we might want to create tests that function even if we don’t have the hardware to hand, which run more quickly than would be the case if we ran on real hardware, and where we can use mocks to simulate errors or other situations difficult to reproduce on demand.

The code for this example is available on GitHub.

  1. Create a directory for our new project:
    $ mkdir mockturtle
    $ cd mockturtle
  2. Create a build definition file called build.sbt containing:
  3. name := "Mock Turtle"
     
    version := "2.0"
     
    scalaVersion := "2.9.1"
     
    libraryDependencies ++= Seq(
      "org.scalatest" %% "scalatest" % "1.6.1" % "test",
      "com.borachio" %% "borachio-scalatest-support" % "latest.integration"
    )
  4. Create src/main/scala/Turtle.scala containing:
    package com.example
     
    trait Turtle {
      def penUp()
      def penDown()
      def forward(distance: Double): (Double, Double)
      def turn(angle: Double)
      def getAngle: Double
      def getPosition: (Double, Double)
    }
  5. The turtle API is not very convenient, we have no way to move to a specific position, instead we need to work out how to get from where we are now to where we want to get by calculating angles and distances. Here’s some code that draws a line from a specific point to another by doing exactly that.

    Create src/main/scala/Controller.scala containing:

    package com.example
     
    import scala.math.{atan2, sqrt}
     
    class Controller(turtle: Turtle) {
     
      def drawLine(start: (Double, Double), end: (Double, Double)) {
        moveTo(start)
     
        val initialAngle = turtle.getAngle
        val deltaPos = delta(start, end)
     
        turtle.turn(angle(deltaPos) - initialAngle)
        turtle.penDown
        turtle.forward(distance(deltaPos))
      }
     
      def delta(pos1: (Double, Double), pos2: (Double, Double)) = 
        (pos2._1 - pos1._1, pos2._2 - pos1._2)
     
      def distance(delta: (Double, Double)) = 
        sqrt(delta._1 * delta._1 + delta._2 * delta._2)
     
      def angle(delta: (Double, Double)) = 
        atan2(delta._2, delta._1)
     
      def moveTo(pos: (Double, Double)) {
        val initialPos = turtle.getPosition
        val initialAngle = turtle.getAngle
     
        val deltaPos = delta(initialPos, pos)
     
        turtle.penUp
        turtle.turn(angle(deltaPos) - initialAngle)
        turtle.forward(distance(deltaPos))
      }
    }
  6. So let’s test that this is doing the right thing. We’ll create a mock Turtle that pretends to start at the (0, 0) and verifies that if we ask the code we’ve just written to draw a line from (1, 1) to (2, 1), it performs the correct sequence of turns and movements.

    Create src/test/scala/ControllerTest.scala containing:

    package com.example
     
    import org.scalatest.Suite
    import com.borachio.scalatest.MockFactory
    import scala.math.{Pi, sqrt}
     
    class MockFunctionTest extends Suite with MockFactory {
     
      val mockTurtle = mock[Turtle]
      val controller = new Controller(mockTurtle)
     
      def testDrawLine() {
        inSequence {
          mockTurtle expects 'getPosition returning (0.0, 0.0)
          mockTurtle expects 'getAngle returning 0.0
          mockTurtle expects 'penUp
          mockTurtle expects 'turn withArgs (~(Pi / 4))
          mockTurtle expects 'forward withArgs (~sqrt(2.0))
          mockTurtle expects 'getAngle returning Pi / 4
          mockTurtle expects 'turn withArgs (~(-Pi / 4))
          mockTurtle expects 'penDown
          mockTurtle expects 'forward withArgs (1.0)
        }
     
        controller.drawLine((1.0, 1.0), (2.0, 1.0))
      }
    }
  7. Run the tests with sbt test. You should see “[success]“

So how does this work? First, we create a mock object that implements the Turtle trait, and pass that to an instance of Controller that we’ll test later:

  val mockTurtle = mock[Turtle]
  val controller = new Controller(mockTurtle)

Then, in our test, we start by setting up what we expect to happen. In this case, ordering is important, so we ensure that our functions are called in order using inSequence:

    inSequence {
      // expectations
    }

We list which methods we expect to be called, together with their arguments. In addition, where it’s important for the functionality we’re testing, we also specify the values that our mock object should return. There’s a wrinkle, however, because we’re dealing with floating-point numbers. If we test for simple equality, rounding errors are likely to stop our tests from passing. That’s where the ~ (tilde) operator comes in:

      mockTurtle expects 'forward withArgs (~sqrt(2.0))

This says that we expect the forward method to be called with a single argument which is “close to” √2. Borachio also supports wildcard parameters (not used here) specified with an * (asterisk).

Finally, we call our code under test with the appropriate arguments:

    controller.drawLine((1.0, 1.0), (2.0, 1.0))

Updated 2011-09-21

Updated for sbt 0.10.x and Borachio 1.3.

Announcing Borachio: Native Scala mocking

Borachio is now ScalaMock.

I’ve recently been working in my spare time on a native Scala mocking framework.

I now have something which, although far from “done”, is close enough that I think it should be useful. So I’d like to announce and solicit feedback on Borachio – a native Scala mocking framework:

Homepage: http://borachio.com/
GitHub: https://github.com/paulbutcher/borachio
Documentation: http://borachio.com/api/com/borachio/package.html

A couple of examples:

def testTurtle {
  val t = mock[Turtle]
 
  t expects 'penDown
  t expects 'turn withArgs (90.0)
  t expects 'forward withArgs (10.0)
  t expects 'getPosition returning (0.0, 10.0)
 
  drawLine(t)
}
def testFoldLeft() {
  val f = mockFunction[String, Int, String]
 
  f expects ("initial", 0) returning "intermediate one"
  f expects ("intermediate one", 1) returning "intermediate two"
  f expects ("intermediate two", 2) returning "intermediate three"
  f expects ("intermediate three", 3) returning "final"
 
  expect("final") { Seq(0, 1, 2, 3).foldLeft("initial")(f) }
}

Formula Jedi 2011 Draft Calendar

Subject to change!

2nd April: Oulton Park International
24th/25th April: Snetterton 300
4th/5th June: Cadwell Park
23rd/24th July: Donnington Park
27th/28th August: Rockingham
24th/25th September: Anglesey
22nd October: Silverstone (new International)

Debug It! reviewed on The C#rypt

I feel like armored with all this knowledge I am ready to become a one man Anticimex army for software bugs. Now it has been a while since I read the book but I remember solving bugs with a new confidence while reading it and after. Strongly recommended for everyone doing software development in any form.

The C#rypt

For more reviews, see Debug It! Review Roundup.

Language Expressivity is all about Scale

Recently, while working on SwiftKey, I’ve found myself writing significant quantities of C++, Java, Python, Ruby and Scala. And switching back and forth between these languages has got me thinking about expressivity.

The expressivity of a language is a difficult concept to pin down. It’s something that anyone who’s used more than one language will develop an intuition for, but how do you explain why one language is more expressive than another? I’ve recently convinced myself that it boils down to the scale at which a language makes it convenient to use a particular type of abstraction.

Here’s an example. I recently found myself writing a Java class which contained several methods that like this:

public void doSomething() {
  synchronized(resource) {
    if(!resource.isReady())
      throw new ResourceNotReadyException();
 
    // doSomething-specific code
  }
}
 
public void doSomethingElse() {
  synchronized(resource) {
    if(!resource.isReady())
      throw new ResourceNotReadyException();
 
    // doSomethingElse-specific code
  }
}

This kind of duplication makes me nervous, so naturally I would like to get rid of it. Before looking at how to do this in Java, let’s look at how I could remove this duplication in Scala:

def claimResource(action: => Unit) {
  synchronized(resource) {
    if(!resource.isReady())
      throw new ResourceNotReadyException()
 
    action
  }
}

This would enable me to write the doSomething and doSomethingElse methods like this:

def doSomething() {
  claimResource {
    // doSomething-specifc code
  }
}
 
def doSomethingElse() {
  claimResource {
    // doSomethingElse-specifc code
  }
}

There’s nothing whatsoever to stop me from doing something very similar in Java. Here’s what it might look like:

void claimResource(Runnable action) {
  synchronized(resource) {
    if(!resource.isReady())
      throw new ResourceNotReadyException();
 
    action.run();
  }
}

Which I could use like this:

public void doSomething() {
  claimResources(new Runnable() {
    public void run() {
      // doSomething-specific code
    }
  });
}
 
public void doSomethingElse() {
  claimResources(new Runnable() {
    public void run() {
      // doSomethingElse-specific code
    }
  });
}

Eugh!

At some level, the Java and the Scala are “the same”, but the additional boilerplate associated with the Java solution makes me question whether I’ve actually made the code any better—I’ve removed the duplication, but at the expense of adding quite a bit of additional boilerplate. So much so that, in this case, I chose to live with the duplication.

Scala makes this kind of thing so easy that I don’t think twice about it. Java makes it difficult enough that I only consider this kind of approach for “big” problems.

There’s no abstraction, in any language, that I can’t find a way to use in any other language. The question is how many hoops I need to jump through to get there and whether the problem is large enough to make that hoop jumping worth the effort.

At the limit, if I’m using (say) C and there’s some wonderful abstraction in (say) Lisp that would make my life much easier, I can just write a Lisp interpreter in C. But the cost of doing so is huge. So much so, that I would only consider it for a really large problem (perhaps this is a corollary of Greenspun’s Tenth Rule?).

So, what makes a language expressive? The more expressive the language, the smaller the scale at which it allows us to apply abstractions.

Android library project with tests, step by step

Warning! Android Tools r14 and (sadly, still) r15 seem to have completely broken the Ant build system with regard to both testing and library support. If you haven’t already upgraded, I strongly suggest that you don’t until these problems are addressed. Here are links to some of the problems:

http://code.google.com/p/android/issues/detail?id=21720 http://code.google.com/p/android/issues/detail?id=21304 http://code.google.com/p/android/issues/detail?id=21299 http://code.google.com/p/android/issues/detail?id=21276 http://code.google.com/p/android/issues/detail?id=21194 http://code.google.com/p/android/issues/detail?id=21108 http://code.google.com/p/android/issues/detail?id=20997

In Testing a library project the Android documentation says:

There are two recommended ways of setting up testing on code and resources in a library project:

  • You can set up a test project that instruments an application project that depends on the library project. You can then add tests to the project for library-specific features.
  • You can set up a set up a standard application project that depends on the library and put the instrumentation in that project. This lets you create a self-contained project that contains both the tests/instrumentations and the code to test.

How to achieve the first of these is pretty obvious, but the second (to me, at least) rather less so. I wasn’t able to find an example, so I thought that I’d post how I managed to get it working.

Although it does work, I’m not 100% happy with it, and there may well be a nicer way to achieve this (see the end of this post for a discussion about my concerns). I would be very grateful for any suggestions for improvements.

Note, we don’t build with Eclipse (partly because we’ve found its reliability leaves a lot to be desired, but mainly because we need a command line build in order to be able to integrate with the rest of our build system and continuous integration server). So all of the following uses the Android command line tools.

The steps

  1. Create a new library project as follows:
    android create lib-project -n ExampleLib -t android-8 \
    -p examplelib -k com.example.lib
  2. In that project, create src/com/example/lib/Widget.java containing:
    package com.example.lib;
     
    public class Widget {
        public String getColour() {
            return "blue";
        }
     
        public String getDisposition() {
            return "awesome";
        }
    }
  3. In the examplelib directory, create a test project with:
    android create test-project -m .. -p test -n ExampleTest
  4. Edit the AndroidManifest.xml in the test project and change the line:
    android:targetPackage="com.example.lib"

    to:

    android:targetPackage="com.example.lib.tests"
  5. Delete the following line from the build.properties in the test project:
    tested.project.dir=..

    and add the following:

    android.library.reference.1=..
  6. Delete the src/com/example/lib/ACTIVITY_ENTRY_NAMETest.java file.
  7. Create src/com/example/lib/WidgetTest.java containing:
    package com.example.lib;
     
    import junit.framework.TestCase;
     
    public class WidgetTest extends TestCase {
     
        private Widget widget;
     
        @Override
        protected void setUp() {
            widget = new Widget();
        }
     
        public void testColour() {
            assertEquals("blue", widget.getColour());
        }
     
        public void testDisposition() {
            assertEquals("awesome", widget.getDisposition());
        }
    }
  8. Start an emulator and install with ant install.
  9. Run the tests with:
    adb shell am instrument \
    -w com.example.lib.tests/android.test.InstrumentationTestRunner

Reservations

It’s clear from the above that the Android tools (the command line tools, at least—perhaps the Eclipse plugin is better?) don’t really fully support this way of working. Not least the fact that they assume that we’re always testing an activity in another application (hence the strangely named ACTIVITY_ENTRY_NAMETest.java file).

  1. In step 4, we changed the targetPackage. This is necessary because if we leave it as com.example.lib, Android will try to launch an application with that package name, which doesn’t exist. However, it’s something of a lie to suggest that the targetPackage is com.example.lib.tests
  2. In a normal Android test project, we can run the tests by typing:
    ant run-tests

    We have to run the tests explicitly with adb, however, because in step 5, we deleted the tested.project.dir line. If we don’t, the ant build system will try to rebuild the library project (and library projects can’t be build independently).

    An alternative to the solution presented above is to set tested.project.dir to the current directory (.). This enables ant run-tests, but at the expense of building the project twice.

So, it all works, but it’s a bit messy. Suggestions for improvements very welcome!

Update

Updated to simplify WidgetTest to use JUnit directly instead of InstrumentationTestCase.

Debug It! reviewed on ElegantCode

This book is highly recommended as it contains a whole lot of wisdom and experience from the field of software engineering. It’s only 190 pages, so you should be able to get through very quickly. So, you can’t lose on this one.

ElegantCode

For more reviews, see Debug It! Review Roundup.

Oulton Park didn’t go as smoothly as it might

Went testing at Oulton on Friday, intending to work on tyre temperatures (because I suspect that this might be part of why I’m consistently in the top 3 during the first 5 minutes of qualifying/the race, but gradually drop down the order after that). And ended up doing no running and having to cope with 3 inches of water in the paddock.

Then race day went like this:

  • Wet at the start of qualifying but with a rapidly developing dry line. Came in after 4 laps to change to slicks (well done crew for getting me out, F1-style, in time for one flying lap!).
  • Thought that I had everything ready for the first race, and then had to perform emergency surgery to the oil system after the car dumped all its oil over the undertray with just under 60 minutes to go). On the plus side, at least it happened in the paddock, not on track!
  • Torrential downpour on the green flag lap while we were all on slicks, leading to the clerk of the course taking the (probably very sensible) decision not to start us.
  • Much dithering over lunch about whether we should start the race on wets or slicks. I chose wets, which turned out to be the wrong decision, resulting in this.
  • Emergency front brake disc change before the second race, after noticing that one of the pads had just disappeared (3 pads with plenty of meat left, one down to the metal – still not sure why).
  • Great battle in with the front-runners for the first 4 laps, at which point my recurring oil temperature problem, which we thought we’d fixed by having the car re-mapped last week, resurfaced :-( Then started dropping back – so we now think that maybe my problem isn’t tyre temp, but oil temp leading to reduced power.

So we’re going to bung a new oil rad on and see what happens.

Motor racing eh?

Great Expectations

Here is the example source code to my PragPub article Great Expectations.