A simple SBT build for your Scalatron bot

Recently, the Scala world got richer again – we now have our own educational robot wars hacking environment: Scalatron.

Unfortunately, it’s not yet well documented or obvious how to set that environment up, except for a huuuge instructions document for IntelliJ IDEA. I mean, 13 pages?! – That just has to be doable in an easier way!

As I’m an Eclipse user and somewhat fluent with SBT, I thought I’d try to setup Scalatron with an SBT build. With the sbteclipse (and sbt-idea) plugins, I’ll then get the IDE setup for free.

So, let’s create a basic SBT build file. As I already suspect that I’ll need a build that’s a bit more complicated than a few lines of configuring standard settings, let’s start with a Build.scala file:

import sbt._
import Keys._

object Build extends Build {
  val bot = Project(
    id = "mybot",
    base = file("."),
    settings = Project.defaultSettings ++ botSettings)

  val botSettings = Seq[Setting[_]](
    organization := "de.johoop",
    name := "my-scalatron-bot",
    version := "1.0.0-SNAPSHOT",

    scalaVersion := "2.9.1",
    scalacOptions ++= Seq("-deprecation", "-unchecked"))
}

This simply initializes my bot project and adds a few standard Scala options I usually like to use.

Next, I want to add the dependency to the Scalatron jar file to the project. As Scalatron isn’t published anywhere, I’ll just create a lib directory and put the jar file from the Scalatron distribution in there.

Another basic thing that’s still missing from the build is the configuration of some kind of tests. I absolutely want to write tests against my bot’s functionality, as it’s very difficult to debug a bot during a running bot war. I’ll use Specs2 for that, of course, because it’s all kinds of genius. We’ll add the following lines to our botSettings:

      libraryDependencies ++= Seq(
        "org.specs2" %% "specs2" % "1.8.2" % "test",
        "org.pegdown" % "pegdown" % "1.0.2" % "test",
        "junit" % "junit" % "4.7" % "test"),

      testOptions := Seq(
      	Tests.Filter(_ == "de.johoop.scalatron.BotSpec"),
      	Tests.Argument("html", "console")),

      testOptions <+= crossTarget map { ct =>
        Tests.Setup { () =>
          System.setProperty("specs2.outDir",
              new File(ct, "specs2").getAbsolutePath)
        }
      },

The first few lines add all required dependencies: pegdown for the nice HTML reports, junit for running the tests from within Eclipse using JUnit.

Then I tell SBT to just execute my main test specification called BotSpec and ignore any sub specifications. And I tell it to create HTML reports, too, and where to put them.

I can now already hack and test my bot to my heart’s content. However, I can’t yet try it out in the Scalatron environment. Let’s do something about this. I need a way to start the Scalatron simulation, and I probably want to configure the directory where all the bots are kept (the enemy bots as well as my own).

For this, I first create two simple SBT keys and add them to the Build class:

  val botDirectory = SettingKey[File]("bot-directory")
  val play = TaskKey[Unit]("play")

The botDirectory setting will simply be initialized to where I want to keep the bots (in the botSettings sequence):

      botDirectory := file("bots"),

The play task will have the job to take my bot jar and deploy it into the bot directory, and then to start a (forked) Scalatron simulation. In order to be able to do this, it will require quite a few dependencies as inputs:

  • botDirectory: where the bots go,
  • name: in order to name my bot in the bot directory,
  • javaOptions: so that I can configure memory settings and the like for the simulation,
  • unmanagedClasspath in Compile: to retrieve the Scalatron.jar from and finally
  • Keys.`package` in Compile: to retrieve my bot’s jar from.

So, here we go (again, at this to the botSettings):

      play <<= (botDirectory, name, javaOptions,
                unmanagedClasspath in Compile,
                Keys.`package` in Compile) map {
                  (bots, name, javaOptions, ucp, botJar) =>

        IO createDirectory (bots / name)
        IO copyFile (botJar, bots / name / "ScalatronBot.jar")

        val cmd = "java %s -cp %s scalatron.main.Main -plugins %s" format (
            javaOptions mkString " ",
            Seq(ucp.files.head, botJar).absString,
            bots.absolutePath)
        cmd run
      }

And that’s it!

I can now deploy my bot to the bot directory and run the simulation from within SBT just by typing play into the SBT console.

Except… except that I noticed that the simulation seems to use a lot of memory, so I added a java option for this:

  javaOptions += "-Xmx1g"

And also, the Eclipse project I generate via the sbteclipse plugin unfortunately warns me about two Scala runtimes (one generated by the plugin, one inside the Scalatron jar). I won’t do anything against this, hoping that we’ll soon get a clean published Scalatron jar that doesn’t automatically include the Scala runtime…

Here’s my complete build file as a gist.

Now go and create your own Scalatron bot! :)

Posted in Scala at March 31st, 2012. 3 Comments.

Accessing the Heroku REST API via Dispatch

Now that I have an extremely simple Heroku app up and running (see my previous post) and don’t know what to do with it, the logical next step for me was to check out Heroku’s REST API. :)

Ok, so first, let’s look up the REST API documentation…

… but wait, such an abstruse beast does not exist! – Instead, we get the Ruby sources of the Heroku REST client. That’s fine with me, except that I don’t speak Ruby so well. But never mind, this looks easy enough.

Let’s check out what to use as REST client API in Scala: Restlet, Jersey or something? – Nooo! Let’s use Dispatch. Dispatch wins the coolness competition hands down, if you ask me. You’ll see below, I hope.

Of course, I’ll use sbt for building my little project. We add the following two dependencies and are done with it:

libraryDependencies ++= Seq(
  "net.databinder" %% "dispatch-http" % "0.8.5",
  "net.databinder" %% "dispatch-lift-json" % "0.8.5")
}

Now let’s import all the good stuff:

import dispatch._
import liftjson.Js._

import net.liftweb.json._
import JsonParser._

I’m going to prepare a few helpers next, and then we’re ready to rumble:

implicit val formats = DefaultFormats

val http = new Http
private val user = "*my-heroku-user*"
private val password = "*my-heroku-password*"

val herokuApi = :/("api.heroku.com", 443).as(user, password)
val herokuHeaders = Map(
    "Accept" -> "application/json",
    "X-Heroku-Api-Version" -> "2")

Next, we can login, for example. This will return our api key, mostly (I don’t know yet what it’s good for though, seeing all the basic authentication that’s going on in the Ruby client).

def login = {
  http(resource(herokuApi / "login")
    < < Map("username" -> user, "password" -> password)
    ># (_.extract[User]) )
}

def resource(request: Request) =
  request.secure <: < herokuHeaders

(The "< <" and "<: <" above should really be "<<" and "<:<", don't ask me why WordPress puts in a space each time I save this post)

Wait, what's User? I have to define that before the above will work. It's just a simple case class which will be filled by Lift-JSON. And when I'm already at it, I'll define the case class for the next request here, too:

case class User(
    email: String,
    api_key: String,
    verified_at: Option[String])

case class HerokuApp(
    id: Int,
    name: String,
    stack: Option[String],
    requested_stack: Option[String],
    slug_size: Int,
    repo_size: Int,
    dynos: Int,
    workers: Int,
    created_at: String,
    create_status: String,
    repo_migrate_status: String)

Now I can call login and will receive something like this:
User(*my-heroku-user*,*my-api-key*,None)

This is fun!

Let's use the above HerokuApp case class to request our current Heroku apps:

def apps = http(resource(herokuApi / "apps")
    ># (_.children map (_.extract[HerokuApp])))

Uhm... - yup, that's all there is to it. This returns a convenient list of apps I have running on Heroku:
List(HerokuApp(*my-id*,*my-app-name*,Some(cedar),None,*large-number-1*,*large-number-2*,0,0,2011/10/10 11:52:03 -0700,complete,complete))

This is great, isn't it? - I at least had no idea that it would turn out to be so very easy to connect to Heroku from Scala.

I still don't know what to put up on Heroku, though...

Posted in Scala at October 11th, 2011. 6 Comments.

Scala on Heroku (using Ubuntu): Addendums to the Tutorial

So, I thought to myself: Heroku sounds pretty cool, let’s try it out… – there is a detailed “Getting Started” out there, so what can possibly go wrong?

Right, that’s what I thought. And yet again, I have learned that I’m being a tad too optimistic.

Without further ado, here’s what went wrong for me and how I fixed what I managed to fix (as a total Ruby newbie):

Prerequisites

No problem here, registration was instant and went smoothly. – sbt 0.11, OpenJDK 6, basic Scala knowledge, all there ready to go.

Local Workstation Setup

Unfortunately, the Ubuntu readme failed me:

  • Minor nitpick, but you should have told me to run those commands as root (yes, I’m such a newb).
  • Running the commands from the readme went smoothly.
  • However, “heroku login” failed with “ruby: command not found“. Hmm… – I’m sorry, but I don’t know anything about Ruby.
  • Let’s try the usual Ubuntu magic: “sudo apt-get install ruby“. Works, yay! Now I can login to heroku from the command line just fine.

Write Your App

Finally, some Scala code, I feel right at home here.

Declare Dependencies with sbt, Add the Start Script Plugin, Build Your App

I’m cool with sbt magic, too. Everything went fine. This looks promising.

Declare Process Types With Foreman/Procfile

Foreman and Procfile? Never heard of these. No problem, I guess, looks easy and helpful. However, my Ubuntu system doesn’t know anything about Foreman either: “foreman: command not found“.

I’m stumped here. I’ve found out that it’s a Ruby gem, and that it should have been installed together with the Heroku Toolbelt. I even tried installing it via “gem install foreman” (which required installing the rubygems package first).

Why do I have to use Foreman here at all?

… turns out: I don’t. I can start my new web application via “target/start Web” just as well. Good enough for me and my experiments.

(The web application started on port 8080 for me though, not on port 5000 as mentioned in the tutorial.)

Store Your App to Git

But I don’t want to. I want to store it to Mercurial instead. Never mind me, though, everyone else loves Git, so you probably love Git, too.

Anyway, this worked like a charm.

Deploy to Heroku/Cedar

This mostly worked, too. “heroku logs” failed at first (“Logging is not enabled for this app.”). A few minutes later, however, it worked. I didn’t change anything, I swear. This is minor anyway, as activating the logging plugin would have been very easy.

And here I am, with a working Scala web app deployed to Heroku. In spite of all my nitpicking: This is cool!

Now I just have to decide what the heck to do with that web app? :)

By the way, the “slug size” of this teeny weeny little app is > 40 MB. This sounds like quite a lot, especially when Heroku tells me that 100 MB is the maximum. How come? – I don’t know. My local git repo is very small, I think. Is it the dependencies, maybe (finagle-core)?

Posted in Scala at October 10th, 2011. 2 Comments.

A few short notes on converting SBT plugins to 0.10.x

I just finished converting my FindBugs SBT plugin findbugs4sbt to SBT 0.10.x.

FindBugs? What’s that? – Go have a look at its website, and then use it, always! One caveat though: It doesn’t support Scala source code. So use it with all your Java projects.

SBT? What’s that? – It’s a Scala-based build tool called “Simple Build Tool”, and it’s cool. Have a look at it and try it out!

Anyway, if you already know about SBT and think about moving over to the new 0.10.x version, or if you even think about hacking your own plugin for it (please do!), the following quick notes may be of interest to you…

  • Read the SBT wiki page about plugins first. It’s not perfect, but it’s a good start, and you could always help improving it.
  • SBT 0.10.x has changed so much that it’s a rewrite, mostly. Give up your hope of “simply converting” your plugin.
  • However, the new settings system seems well thought-out. Forget the trait- and override-based system of 0.7.x. You know you want to.
  • You want to take a look at this SBT source file. Believe me. You just don’t know yet that you do. Knowing the settings keys is absolutely vital for hacking plugins.
  • Take a good long look at all the existing plugins‘ source code. They’re all doing different things in different ways, and all in all, there’s a lot to learn from them.
  • Quick, learn the difference between SBT tasks and commands. In my humble opinion, task plugins are probably easier to write than command plugins.
  • Don’t be afraid to read and ask questions in the SBT Google Group.
  • Don’t use SBT 0.9.9. It’s the one slow version of SBT, and I used it for most of my plugin conversion, so that you don’t have to, too. :)
  • Please don’t put everything into one plugin source file. There are other people out there who want to learn how to create their own SBT plugins, and they want to be able to read and understand your code.
  • Browse the SBT API documentation and use the stuff that’s already in there. It’s a lot, even if it’s perhaps not so easy to find your way around in there (at least it hasn’t been for me).
  • Maybe, you want to consider comparing the sbt-0.7.x and the default branch of my findbugs4sbt plugin, if you want to convert something task-based and are after a “before” vs “after” comparison.

So there you have it, a few of my insignificant and unordered plugin conversion impressions. I hope you’ve had fun reading them.

Posted in Scala at June 7th, 2011. 5 Comments.

Four reasons why SWTBot doesn’t work out (for me)

After my little blog series about Jubula, I thought I’d try out something similar using SWTBot. However, there’s no use in writing the same tutorial again for the RCP mail application because it’s already there

Nevertheless, I attempted to implement the same few tests I wrote for Jubula, and you can view the results in the piece of code below:

package de.johoop;

import static org.junit.Assert.*;

import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.swt.finder.keyboard.Keystrokes;
import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
import org.junit.Before;
import org.junit.Test;

public class FirstSwtBotTest {

  private SWTWorkbenchBot bot;

  @Before
  public void setUp() throws Exception {
    bot = new SWTWorkbenchBot();
  }

  @Test
  public void mailToolbarButtonShouldOpenMessageDialog()
      throws Exception {

    bot.toolbarButton(1).click();
    assertThatCorrectDialogIsDisplayed();
  }

  @Test
  public void openMessageMenuEntryShouldOpenMessageDialog()
      throws Exception {

    bot.menu("Open Message").click();
    assertThatCorrectDialogIsDisplayed();
  }

  @Test
  public void keyboardShortcutShouldOpenMessageDialog()
      throws Exception {

    SWTBotPreferences.KEYBOARD_LAYOUT = "EN_US";
    bot.activeShell().pressShortcut(
        Keystrokes.CTRL, KeyStroke.getInstance("3"));
    assertThatCorrectDialogIsDisplayed();
  }

  private void assertThatCorrectDialogIsDisplayed() {
    final SWTBotShell openDialog = bot.activeShell();
    assertEquals("Open", openDialog.getText());
    assertTrue(bot.label("Open Message Dialog!").isVisible());

    bot.button("OK").click();
    assertFalse(openDialog.isOpen());
  }
}

It’s a set of three tests opening the “Open Message” dialog via toolbar button, keyboard shortcut or menu entry. Simple.

At first glance, this looks neat, especially if you’re a developer: few lines of code, all directly in Java, using the already familiar JUnit framework, well supported from within the Eclipse IDE.

Nevertheless, here’s my list of things I don’t like about this:

  1. Let’s begin with a minor nitpick: I’m using a German keyboard layout, and SWTBot complains that it can’t find my layout. This means that I either have to somehow create one (which might be easy, I haven’t checked), or I have to set my keyboard layout to the US one (it doesn’t matter for my simple Ctrl-3 test).
  2. Next, I can’t write these tests in Scala for some reason (I’d really like to use Scala for my tests, so very much more concise): In Scala, the following line:
    new SWTWorkbenchBot().toolbarButton(1).click()

    fails with a compile error in Eclipse: “Access to protected method click not permitted because enclosing class object ScalaUser is not a subclass of class AbstractSWTBot in package widgets where target is defined”. – What’s that?

    If you ask me, it’s somehow caused by the SWTBotToolbarButton having an abstract public method click() returning an SWTBotToolbarButton, and inheriting from AbstractSWTBot<T>, which has an abstract protected method click() returning an AbstractSWTBot<T>.

  3. Also, I don’t want to use JUnit for system tests. JUnit is a great framework if all you do is unit tests. If you’re testing on the level of integration or system tests, however, TestNG is a way better fit if you ask me. The execution model of TestNG is a lot more flexible than that of JUnit (even if you use decorators and stuff there). For example, have a look at the data providers of TestNG. Unfortunately, there’s no TestNG integration for SWTBot.
  4. Finally, here’s what I’d call a showstopper. Have you noticed how I say toolbarButton(1) in my code instead of the toolbarButtonWithTooltip("Open Message") you’d probably expect? That’s because using the latter method will require another dependency in your plug-in project. That dependency will have to get injected into your test object, too (the RCP mail application in my case). And unfortunately, it will add toolbar buttons and keyboard shortcuts to your test object!

    In my case, this leads to Ctrl-3 suddenly not working as expected anymore: The tests have changed the behaviour of the test object! I absolutely can’t have that happening.

For me, these four reasons unfortunately mean that SWTBot is not a viable tool for automating UI tests. I would really like to use it, especially combined with Scala, for quick and easy developer UI testing; I’d be quite happy if you could refute any of my four reasons above.

I’ve still got hope that maybe I’m just too stupid to use SWTBot correctly.

Posted in Eclipse, Java, Scala, Testing at May 25th, 2011. 3 Comments.

UI Testing with Eclipse Jubula: Executing the Tests (3)

In my last blog post, everything was pure theory (if you’re looking for the start of the Jubula series, look here): I specified a few tests, but there’s no connection yet to any real application under test. Let’s rectify this!

Before starting up Jubula today, look for the “AUT Agent” service and start it. The AUT Agent is our connection to the “real world”. It takes commands from Jubula and executes them on the application under test (you can even run Jubula and the agent on different boxes for distributed testing). On Windows, you might have to start the agent via “Run as Administrator”.

Next, start Jubula and open your project. Now, look for the “Connect to AUT Agent” toolbar button and press it in order to establish the connection to the agent we started before:

Next, start the test object via the “Start AUT” toolbar button. You should then see its ID listed in the “Running AUTs” view:Running the application under test

The application under test is running now, and you can view it on your screen. However, we still can’t run any tests, as the logical components we specified last time are not yet mapped to their real component counterparts within the RPC application. Let’s fix this by starting the “Object Mapping Mode”, again from the toolbar:Starting the Object Mapping

Now activate the test object and move the mouse around within it. Notice the green borders around the various components? That’s the Jubula Object Mapper showing you the components it has detected. In order to add any of these to your object mapping, you have to press Ctrl-Shift-Q.

You can collect all components at once like that if you want to, but I’d advice against it because it can get crowded and confusing quickly in Jubula when you do that. Instead, start with the few components we currently require for our tests to run. In my case, this would mean capturing the mail icon in the toolbar, and – after clicking it – the dialog message text and the dialog “Ok” button.

When done, switch back to Jubula. You should see a new editor called “OM / <something>”, already containing your logical components on the left side, and the newly recorded test object components on the right side:Unmapped components

All that’s left to do now is to map the logical to the technical component names. You can do this by dragging each logical component name over the respective technical one and drop it there. The editor will change into this:All objects mapped

Aaand… – we’re done with the object mapping. Your “Problems” view should be empty. This means that we can run our tests, at last! – Ok, nearly. First, we have to stop the object mapping mode again. I’m sure you’ll find the respective toolbar button by yourself. :)

Select your “System Test” test suite in the “Test Suite Browser” view and run it:Running the Test Suite

Hopefully, your automated tests will run now. – You can switch into the Test Execution afterwards and check the results of the test run:

Oops, my tests failed. What’s the matter?

I’ll go check the screenshot Jubula captured when the “wait for window” action failed. It shows a second message tab being open, and zero “Open Message” dialogs. Hmmm…

Oh right, I accidentally mapped the wrong toolbar button to my logical “Open Message” component… – I should have mapped the mail button to it, instead of the green plus sign.

I’ll correct that (for some reason, I had to restart Jubula before it accepted my fixed object mapping), and maybe you’ve got a few things to correct, too, and then we’re done!

You’ll notice that there will always be some debugging of your test specifications going on here, unfortunately, but that’s to be expected: Specifying tests is like developing in a lot of ways. Also, finding out what exactly made your tests fail can sometimes be harder than it looks, screenshots or not.

Alright, let’s summarize what we’ve achieved up to here:

  • In the first part of my blog series, there was some configuration to do in order to get the application under test to cooperate with Jubula. A one time effort.
  • In the second part, we specified a few tests. This is the part you’ll have to put the most effort into. You absolutely want to get your test specifications right: Clear, concise, complete, robust, maintainable. This is always difficult to get right. However, in my humble opinion, Jubula gives you a lot of good tools for structuring and refactoring your test specifications to simplify this.
  • In the third part, we mapped the components and executed the tests. Yay!

This should be enough about Jubula to get you started with your own experiments. I hope I tempted you into trying it out! – It’s a tool with a lot of potential, at the least.

Before using Jubula in a real-world project, there’s still a lot of things to clarify, of course, like:

  • What kind of database should you use with Jubula (it defaults to an embedded H2)?
  • How well does it cope with multiple team members specifying tests at the same time?
  • How to integrate it into an Ant/Maven/SBT/Gradle/Buildr/whatever build?
  • How to run it on an Continuous Integration server?
  • How well do the exported test specifications play together with version control systems?
  • … and probably more stuff like that…

But it’s a start. :)

Posted in Eclipse, Java, Testing at May 17th, 2011. 8 Comments.

UI Testing with Eclipse Jubula: Specifying the Tests (2)

Last time, I prepared the Eclipse sample RCP mail application as a test object for Jubula. Today, I’ll try specifying a few tests against it in Jubula. If you’ve missed the first part, you can find it here.

What’s that about specifying tests? – Can’t you just capture and replay them, perhaps? – Well, no, not with Jubula, and not with me, either! The reason is that test scripts created via Capture/Replay have lots of problems with maintainability and robustness. And when you try to refactor Capture/Replay scripts into a good automation, you’ll notice that it’s not easier than writing those scripts from scratch with modern test automation tools like Jubula.

Also, Capture/Replay is only possible after the test object already exists (which is normally too late in the lifecycle of a project), and it misleads you into adapting the tests to fit the current behaviour of the test object.

So, let’s start up Jubula and begin specifying a few tests. After the welcome screen, Jubula greets you with the following prim perspective:Jubula: Empty Specification Perspective

If you look at it very closely, you’ll find a small hint about what to do next within the Problems view:Jubula Hints

However, it doesn’t tell you how to create a new project. Surprisingly, you won’t find it in the File menu, but in the Test menu (Test/New…):Creating a new test project, step 1

Choose “rcp” as toolkit, give your project a good name and click the “Next” button. Now you’ve got to tell Jubula about your test object (Jubula calls it “AUT” for “application under test”):Creating a new test project, step 2

Choose a name for your test object and ensure, that the “rcp” toolkit is selected. Don’t worry about AUT IDs for now. Press the “Next” button for the last step: configuring your test object:Creating a new test project, step 3

Give your configuration a good name, and set an “AUT ID” for it, too. But mainly, select the executable of your RCP application, then click “Finish”. – At last, we’re done with creating the test project.

Note (in the top right) that we’ve already got the correct perspective open: the “Functional Test Specification” perspective. When specifying tests in a top-down way, you’ll at first mostly work with the “Test Case Browser” view (bottom left), with the editor pane, of course, and with the “Properties” view (top right).

To begin with, let’s create two levels of abstraction for structuring our tests (for complex applications, you probably want more than two): “Use Cases” and “Basic Interactions”. Create these as new categories in the Test Case Browser. Notice how the “Use Cases” gets sorted (alphabetically) after the system library test cases of your toolkit (“unbound modules…”). If you don’t like that, you can always prefix your categories.

Let’s test the opening of mail messages first. I created another category for that under the “Use Cases”. What are our use cases for opening mail messages in that simple application? Well, we can open a message by menu, by keyboard shortcut or by toolbar button. And afterwards, we can check whether the “Open Message Dialog” appears correctly. That’s it. Here are my test cases:

Alright, now we can open our first test case “Open Message via Menu” in an editor:Empty Test Case Editor

A lot of empty space to fill… – what are the basic interactions this test case consists of? I’d say we have to find and select the correct menu entry first, and then check for the dialog next. So let’s create these two basic interactions (I already created the basic interactions for the other use case level test cases, too):Use Cases and Basic Interactions

Now that we have declared the required basic interactions, we can drag and drop them into the editor, and even rename the references afterwards in the Properties view (not very necessary in this simple case, where there are no parameters, but in general, I’d always do that):

Up to now, we’re still on an abstract level without any toolkit interactions. But that’s going to change when we specify how our basic interactions work.

Let’s start with opening the “File” / “Open Message” menu entry. We’re looking for a way to select a menu bar entry. So, let’s open up the “unbound_modules_concrete” tree in the Test Case Browser, and then look under “Actions (basic) / Select / Menu Bar / ub_mbr_selectEntry_byTextpath”. That should be the right one. Drag it into the Test Case Editor of your basic interaction.

Nearly done. Now give it a good name in the “Properties” view, and set the two parameter values. The value for TEXTPATH should be /File/Open Message*, and the value for OPERATOR should be simple match (or you could do the same with matches and a proper regular expression in TEXTPATH).

Now your test case should look similar to this:

Next let’s specify how to check the dialog: First, we want to wait until an “Open” dialog appears, then we want to check that it displays the correct text, and finally we want to close it again by pressing the “Ok” button. This means, that for this test case, we need a sequence.

So, find the basic concrete action “Wait / Application / Wait for Window / ub_app_waitForWindow” and add it to your test case. You now have to configure a few properties again, namely TITLE, OPERATOR, TIMEOUT_IN_MILLISECS and DELAY_AFTER_VISIBILITY:Wait for the "Open" dialog

Then, find the action “Check / Component with Text / ub_ctx_checkText” and append it to your test case. Enter the parameter values as always. But now, there’s something new to do. We have to tell Jubula the text of which component we want to check, and we do that in the “Component Names” view (in the lower right). In there, under “New Name”, just enter an identifier that makes it easy for you to remember which component it is (I chose “open_message_dialog_text”):Check the text in the dialog

Later, when you want to execute your tests, you’ll need to map these component identifiers to the physical components of your test object. This is called object mapping, but we’ll handle that later on.

Alright. Now, only the button click is missing. It’s in the basic actions category, too, under “Click” / “ub_grc_clickLeft_single”. There’s no properties to set this time (except for the reference name), but again, we have to tell Jubula that we want it applied to the “Ok” button of the dialog by telling it how we want to call our logical component (I chose “open_message_dialog_ok_button”):Click the "Ok" button

And finally, we’re done with our first check.

I’ll leave specifying the two other basic test cases “Open message via toolbar” and “Open message via shortcut”, and filling in the two other use case level test cases to you, as an exercise. :)

When you’re done, we can collect the fruits of our work in a test suite. Within the “Test Suite Browser”, create a new test suite called “System Test” (for example), and open it in an editor. Now drag all your use cases into the test suite:Finally: the complete test suite

Don’t worry if you see problems in the “Problems” view. They probably tell you that you haven’t done the object mapping yet. – We’re done specifying our tests, but we can’t execute them yet!

And that means that there’s more left to do in my next blog entry:)

Posted in Eclipse, Java, Testing at May 15th, 2011. 2 Comments.

UI Testing with Eclipse Jubula: Preparing the Test Object (1)

Recently, Bredex created an interesting product at the Eclipse Foundation: namely, Jubula, a tool for UI testing Eclipse RCP, SWT, Swing and web applications. Basically, I guess this will become the “community edition” of GUIDancer, which is good enough for me, considering the dire need for any free UI testing tool for RCP, SWT or Swing at all.

I won’t go into comparisons with other tools in this post, but in short, imho, though there may be better tools for web testing, though there may be alternatives for Swing testing, though there may be better commercial tools for testing RCP and SWT, when you’re looking for free tools for testing RCP/SWT, I think you should start with Jubula.

Unfortunately, working with Jubula turns out to be a bit unwieldy at first. – So I’ll try to give a detailed step-by-step guide to your first GUI test automation with Jubula here, using a simple Eclipse RCP sample project as the test object.

So, let’s start with setting up the test object first: Open up Eclipse and create a new plug-in project (File/New/Project…/Plug-in Development/Plug-in Project):New Plug-in Project Wizard, Page 1

Next, tell Eclipse that it’s a rich client application:New Plug-in Project Wizard, Page 2

And finally, choose the “RCP Mail” template:New Plug-in Project Wizard, Page 3

Now, let’s see what we’ve got in our workspace:The Mail RCP project, with warnings!

Hey, wait, what’s that, warnings about raw types? – We can’t tolerate that. I’ll quickly fix these by turning the List into a List<TreeObject>:Fixing the warnings

That was easy. Actually, why do they have these warnings in their sample code at all? – Anyway, what’s next? Right, let’s try if it works:Ok, it runs

Looking good. This should be simple enough for our first steps, yet complex enough to play around a bit. – However, for exporting the application, we’re missing a product configuration (File/New/Product Configuration):Creating a product configuration

Alright, now we’re set for exporting the RCP application as Eclipse product (File/Export…/Eclipse product):Exporting the RCP product

Finally, we’re done with preparing our test object. Or are we?

Actually, we’re not, unfortunately. The reason for this is that sadly, the Eclipse JFace/SWT libraries haven’t got any easy way to access/instrument them for automation on the fly (unlike Swing).

So, Jubula has to somehow hook itself into our RCP application, and we have to help with that: Look for the archive rcp-support.zip in your Jubula installation directory and extract it into your product directory. This will add a Jubula instrumentation plugin to your product.

However, that’s not all. You’ve still got to activate that plugin, and you can do that by editing the configuration/config.ini file in your product directory. There’s a long line in that file listing the osgi.bundles, and you have to add the Jubula plugin at the end:Configuring the OSGi bundles

Phew. Now we’re really really done with preparing the test object. Of course, for real projects, you’ll probably want to automate all these preparations in your build.

Let’s start up Jubula and do some testing! – Or wait, actually, let’s do that in my next blog post. :)

Posted in Eclipse, Java, Testing at May 13th, 2011. 11 Comments.

Detecting the Copy/Paste Antipattern from within SBT

I’m in the middle of porting the build process of a few (Java) projects from old and complicated Ant to SBT, trying to fill a few gaps in SBT tooling, especially those that concern those of us sentenced to Java.

I’ve already done FindBugs integration which you can find here. FindBugs works on bytecode, so theoretically, it can work with Scala code, too. However, I’ve heard that it reports a lot of false positives there, as it’s really tailored to Java in practice.

Then, there’s the very useful Copy/Paste Detector from the PMD code analysis suite. I’ve written an SBT plug-in for CPD yesterday, too.

Now, if you ask me, Java is basically Copy/Paste Paradise: Without higher-order functions or closures, there’s always the temptation to just copy all the boilerplate again and again. I had a Java code review project recently where about 40% of the whole codebase was generated by copy/paste!

But of course, this is not Java-specific. You can copy/paste Scala code, too, although in Scala, you should really never have to…

CPD can help you avoid this pitfall. Especially coupled with the nice DRY plug-in for the Hudson Continuous Integration Server, which gives you a pretty good overview of CPD’s results, especially in Brownfield projects.

And now, thanks to me (yay for me!), you can use CPD from within SBT, too.

There’s one drawback, though: CPD doesn’t really support Scala as a language, either. I think it may work sufficiently well using the “Any” language tokenizer they have. But if you want good results, there’s some work to do for you. And looking at the existing tokenizers for the other languages CPD supports, it’s not too much work.

So, is anyone up to adding Scala support to CPD?

Posted in Java, Scala at December 2nd, 2010. 1 Comment.

Hello world (obligatory)!

Here go my humble beginnings of a blog…

  package de.johoop.stupidness

  object HelloWorld {
    lazy val somethingUnexpected = "hello world?!"
    def main(args: Array[String]) {
      println(somethingUnexpected) // yeah right...
    }
  }
Posted in Miscellaneous at November 10th, 2010. No Comments.