Archive for the 'Software Engineering' Category

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) }
}

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.

Great Expectations

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

Debug It! reviewed on LosTechies

I think that this book should be read by all new software developers as well as all junior or mid-level developers. There’s plenty to be learned by the senior developer types too. Even if you’ve been doing these things for a long time, this is a good read to make sure you’re keeping your feet planted firmly on the ground.

lostechies.com

For more reviews, see Debug It! Review Roundup.

Scala compiler advanced options

Recently I found myself trying to find a definitive list of the options supported by scalac, the Scala compiler. It turns out that I could have just asked the compiler itself (the -X option lists all “advanced” options and the -Y option lists all “private” options). But this is very difficult to find via Google.

So I thought that I’d create this page and hopefully save anyone else looking for the same information some time.

$ scalac -version
Scala compiler version 2.8.0.RC1 -- Copyright 2002-2010, LAMP/EPFL

Advanced Options

$ scalac -X
Usage: scalac <options> <source files>
Possible advanced options include:
  -Xassem-extdirs <dirs>         List of directories containing assemblies, defaults to `lib'
  -Xassem-name <file>            Name of the output assembly (only relevant with -target:msil)
  -Xassem-path <path>            List of assemblies referenced by the program (only relevant with -target:msil)
  -Xcheck-null                   Emit warning on selection of nullable reference
  -Xcheckinit                    Add runtime checks on field accessors. Uninitialized accesses result in an exception being thrown.
  -Xdisable-assertions           Generate no assertions and assumptions
  -Xelide-below                  Generate calls to @elidable-marked methods only if method priority is greater than argument.
  -Xexperimental                 Enable experimental extensions
  -Xfuture                       Turn on future language features
  -Xgenerate-phase-graph <file>  Generate the phase graphs (outputs .dot files) to fileX.dot
  -Xlog-implicits                Show more info on why some implicits are not applicable
  -Xmigration                    Warn about constructs whose behavior may have changed between 2.7 and 2.8
  -Xno-forwarders                Do not generate static forwarders in mirror classes
  -Xno-uescape                   Disables handling of \u unicode escapes
  -Xnojline                      Do not use JLine for editing
  -Xplugin-disable:<plugin>      Disable a plugin
  -Xplugin-list                  Print a synopsis of loaded plugins
  -Xplugin-require:<plugin>      Abort unless a plugin is available
  -Xplugin:<file>                Load a plugin from a file
  -Xpluginsdir <path>            Path to search compiler plugins
  -Xprint-icode                  Log internal icode to *.icode files
  -Xprint-pos                    Print tree positions (as offsets)
  -Xprint-types                  Print tree types (debugging option)
  -Xprint:<phase>                Print out program after <phase> or "all"
  -Xprompt                       Display a prompt after each error (debugging option)
  -Xresident                     Compiler stays resident, files to compile are read from standard input
  -Xscript <object>              Compile as a script, wrapping the code into object.main()
  -Xshow-class <class>           Show class info
  -Xshow-object <object>         Show object info
  -Xshow-phases                  Print a synopsis of compiler phases
  -Xsource-reader <classname>    Specify a custom method for reading source files
  -Xsourcedir <directory>        When -target:msil, the source folder structure is mirrored in output directory.
  -Xstrict-warnings              Emit warnings about lots of things.
  -Xwarninit                     Warn about possible changes in initialization semantics
  -Y                             Print a synopsis of private options

Private Options

$ scalac -Y
Usage: scalac <options> <source files>
Possible private options include:
  -Ybrowse:<phase>               Browse the abstract syntax tree after <phase> or "all"
  -Ybuild-manager-debug          Generate debug information for the Refined Build Manager compiler.
  -Ybuilder-debug:<method>       Compile using the specified build manager (none,refined,simple)
  -Ycheck:<phase>                Check the tree at the end of <phase> or "all"
  -Yclosure-elim                 Perform closure elimination
  -Ycompact-trees                Use compact tree printer when displaying trees
  -Ydead-code                    Perform dead code elimination
  -Ydebug                        Output debugging messages
  -Ydetach                       Perform detaching of remote closures
  -Yfatal-warnings               Fail the compilation if there are any warnings.
  -Yide-debug                    Generate, validate and output trees using the interactive compiler.
  -Yinline                       Perform inlining when possible
  -Yjenkins-hashCodes            Use jenkins hash algorithm for case class generated hashCodes.
  -Ylinearizer:<which>           Linearizer to use (normal,dfs,rpo,dump)
  -Ylog-classpath                Output information about what classpath is being applied.
  -Ylog:<phase>                  Log operations in <phase> or "all"
  -Yno-completion                Disable tab-completion in the REPL
  -Yno-generic-signatures        Suppress generation of generic signatures for Java
  -Yno-imports                   Compile without any implicit imports
  -Yno-predefs                   Compile without any implicit predefined values
  -Ypmat-debug                   Trace all pattern matcher activity.
  -Ypmat-naive                   Desugar matches as naively as possible..
  -Yrangepos                     Use range positions for syntax trees.
  -Yrecursion                    Recursion depth used when locking symbols
  -Yrepl-debug                   Trace all repl activity.
  -Yself-in-annots               Include a "self" identifier inside of annotations
  -Yshow-trees                   Show detailed trees when used in connection with -print:phase
  -Yskip:<phase>                 Skip <phase> or "all"
  -Ysqueeze:<enabled>            if on, creates compact code in matching (on,off)
  -Ystatistics                   Print compiler statistics
  -Ystop:<phase>                 Stop after phase <phase> or "all"
  -Ystruct-dispatch:<method>     Selects dispatch method for structural refinement method calls (no-cache,mono-cache,poly-cache,invoke-dynamic)
  -Ysuppress-vt-typer-warnings   Suppress warnings from the typer when testing the virtual class encoding, NOT FOR FINAL!
  -Ytailrecommend                Alert methods which would be tail-recursive if private or final.
  -Ytyper-debug                  Trace all type assignements
  -Ywarn-catches                 Emit warnings about catch blocks which catch everything.
  -Ywarn-dead-code               Emit warnings for dead code
  -Ywarn-shadowing               Emit warnings about possible variable shadowing.

Scala 2.8.0.RC1, sbt and ScalaTest step-by-step

For an updated version of this post that covers Scala 2.9.1 and sbt 0.10, go here.

I spent quite a bit of time beating my head against the details of getting Scala 2.8.0.RC1, sbt and ScalaTest to play nicely with each other. So here’s a step-by-step guide which will hopefully save others time.

  1. Install sbt
  2. Create a new project as follows:
    $ mkdir aproject
    $ cd aproject/
    $ sbt
    Project does not exist, create new project? (y/N/s) y
    Name: aproject
    Organization: com.example
    Version [1.0]: 
    Scala version [2.7.7]: 2.8.0.RC1
    sbt version [0.7.3]:
  3. Create a build configuration file in project/build/AProject.scala containing:
    import sbt._ 
     
    class AProject(info: ProjectInfo) extends DefaultProject(info) { 
      val scalaToolsSnapshots = ScalaToolsSnapshots
      val scalatest = "org.scalatest" % "scalatest" %
        "1.0.1-for-scala-2.8.0.RC1-SNAPSHOT"
    }

    This tells sbt that you will be using the pre-release snapshot version of ScalaTest for Scala 2.8.0.RC1.

  4. Download the ScalaTest library with sbt update. After running this, you should see that you have a lib_managed directory containing the ScalaTest jar.
  5. Create src/main/scala/Widget.scala containing:
    package com.example
     
    class Widget {
      def colour = "Blue"
      def disposition = "Awesome"
    }
  6. Create src/test/scala/WidgetSpec.scala containing:
    package com.example.test
     
    import org.scalatest.Spec
    import com.example.Widget
     
    class WidgetSpec extends Spec {
     
      describe("A Widget") {
     
        it("should be blue") {
          expect("Blue") { new Widget().colour }
        }
     
        it("should be awesome") {
          expect("Awesome") { new Widget().disposition }
        }
      }
    }
  7. Run your tests with sbt test. You should see:
    [info] == com.example.test.WidgetSpec ==
    [info] A Widget
    [info] Test Starting: A Widget should be blue
    [info] Test Passed: A Widget should be blue
    [info] Test Starting: A Widget should be awesome
    [info] Test Passed: A Widget should be awesome
    [info] == com.example.test.WidgetSpec ==
  8. Create src/main/scala/Main.scala containing:
    package com.example
     
    object Main {
      def main(args: Array[String]) {
        val w = new Widget()
        println("My new widget is "+ w.colour)
      }
    }
  9. Run your program with sbt run. You should see:
    [info] Running com.example.Main 
    My new widget is Blue

Update: Use the pre-defined ScalaToolsSnapshots repo (thanks to Erick Fleming).

Update: Fixed a typo in step 8 (thanks to Jason).