CALL +44 (0)20 7183 3893
agile, geeky, and eccentric Dev Blog

Wednesday, May 23, 2012

What I Do: Agile Architect

Software is complicated. You just won’t believe how vastly, hugely, mind-bogglingly complicated it is. Software is probably one of the most challenging and complex things our fair species has ever created. Unsurprisingly, this makes software difficult to produce at all, and incredibly hard to do well.

The process of making software — which we, lovingly, call software engineering — is mostly about managing that complexity. This is done so that humans can cope with it, harness it and do awesome things using it. One of the techniques used to contain complexity is abstraction. Software resembles a Russian doll of abstractions. Each layer brings us an increasingly human viewpoint that gets us closer to the problem domain. If the abstractions are good ones, we can write code in the terms our users can understand. If they are bad, then the Russian doll will resemble a scene from a Cronenberg film.

As an agile architect, my main role on projects is a steering and advisory one. I help guide the software towards good abstractions that contain the complexity. This allows us to deliver high quality code reliably and efficiently. Unlike a traditional software architect, I don't develop huge upfront designs that quickly become dangerously out of date. Instead, I work day-to-day as part of the team; keeping the big picture of the project’s in mind so our talented developers can focus on the functionality they're currently building. This high-level view allows me to step in when needed and offer guidance on how to solve particular problems. It also makes sure our solutions are cohesive, maintainable and flexible.

A lot of what I do is connecting from the business to the technical worlds, taking stories and fitting them into our solution’s jigsaw by translating complex requirements into tangible technical tasks. Working together, our developers and I ensure that the solution we’re developing is the right solution.

I'm usually involved right from the start of a project, building up a deep understanding of what the customer wants to achieve and the constraints they have. I will produce an initial high-level architecture that provides a scaffold from which the system will grow. That initial picture is likely to change as the software develops, but it helps our teams focus their thoughts on developing a great solution user story by user story by protecting them from much of the complexity.

I also have oversight responsibilities across our projects. I encourage our engineers to follow best practices, both technically and procedurally, and assist with organisational learning. I am responsible for validating solutions to keep technical risks to a minimum and with spotting useful patterns in what we develop.

The role of agile architect is an exciting and challenging one that keeps me learning. Every day, I am presented with new puzzles to solve, and the work is incredibly varied. One day the task at hand could be designing a distributed task system and the next I could be working on a line-of-business tablet application with a clever backend. This job gives me the rare privilege of working on some of the most cutting-edge aspects of cloud computing whilst getting to help some of the biggest brands in the UK solve their business problems.

Monday, May 21, 2012

Delivering Enterprise Android Applications Continuously


Siddhu Warrier (siddhu.warrier at cloudreach) 

Continuous Delivery (CD) makes sense on so many levels that I’m not even going try to restate its benefits. There have also been reams written on achieving continuous delivery when you’re in the business of developing, say, web apps. However, there is far less on the continuous delivery of private enterprise Android applications. 

It’s been a while since Cloudreach first got into the business of developing enterprise Android applications that interact with several cloud platforms. When we got started, there was very little by way of support for continuous deployment of Android applications that could not use the Android marketplace. 

Thankfully, though, the last couple of years have seen both the Android platform* and our development processes at Cloudreach mature significantly, as a result of which we have now introduced CD into our agile development process for mobile applications.

1. Wanted: Acceptance Testing framework for Android
We are currently working on a mobile and web application for a major manufacturer. At the very outset, we were very keen to implement CD. But we found that the biggest hurdle that we faced was the absence of an acceptance testing framework like Cucumber. 

It was then that we realised that the lovely folk at www.lesspainful.com decided to open-source Calabash (https://github.com/calabash), an acceptance testing framework for Android that brings Robotium (www.robotium.org) and Cucumber (http://cukes.info/) together. 

And before you could say ‘So that I can write automated acceptance tests’, we had our automated acceptance tests beavering away on our device!

2. Wanted: Private App Deployment and Crash Management System
The second challenge we faced was finding a private Android marketplace and crash reporting solution that was stable, and allowed for in-app upgrades. 

After looking at a fair few, we zeroed in on Hockey App (http://www.hockeyapp.net) because:
  • It provides a RESTful API that allowed us to automate deployments from our CI server.
  • It is cheap at $10 a month for an indie license.
  • It has a reasonably clean SDK
  • It didn’t do anything daft like write crash reports into a spreadsheet that quickly became un-openable.
However, there are a few things I didn’t quite like about HockeyApp. 
  • Why is the SDK an APKlib, and not a JAR? APKlibs are a great idea, but the Eclipse ADT’s support for it isn’t quite there yet.
  • Why is HockeyApp initialised in the application’s “main” activity? This seems to me rather brittle, and not as nice as ACRA’s approach.

3. Wanted: Artifact Deployment Solution
This was the piece of our CD jigsaw that we’d put together first (well before we started thinking of implementing CD). 

We use Maven and artifactory (http://www.artifactoryonline.com) for all of our Java projects, and the Maven Android Plugin (http://code.google.com/p/maven-android-plugin/) fit the bill very well indeed. It also allowed us to structure our Android project in a manner that was consistent with how we did the rest of our Java development.


4. Wanted: A sensible Git branching solution
As we have had occasion to mention previously on this blog, we’re wedded to Git and Github in a loving, stable, and monogamous relationship. We also found the Git Flow branching structure ideal for what we were looking to do.

Putting it all together

We are currently working on fortnightly sprints (we’re evaluating an alternative project management approach which is quite unlike a dime bar on one of our internal projects, but more on that in another post). 

During the course of a sprint, 
  • Every time one of our developers picks a story, he branches from the head of the develop branch to work on it. Once we’re done and the code has been asynchronously reviewed (more on that in another post), we merge the code back into develop, which triggers a build on our Jenkins CI.
  • At the end of the sprint demo, we roll our latest build on develop into the master branch using Git Flow. This triggers our CI, which then runs the full suite of automated tests and sends the aligned bundle to our artifactory repository and to HockeyApp. 
  • In a matter of minutes, our testers and early adopters receive an in-app notification suggesting that they upgrade.
The whole process has cut our deployment cycles down from half an hour or more to approximately 5 minutes of manual effort.

Areas for improvement

There’s a few things still holding us back. These include:
  • The Jenkins Android Emulator plugin has an annoying propensity for wiping the user’s data. This is a particular problem for us, as our app requires the presence of Google accounts on the device. We currently make up for it by triggering acceptance tests on real devices, but this is clearly not ideal.
  • HockeyApp does not allow us to have multiple applications with the same package identifier. This has therefore precluded our efforts to deploy every time we push to the develop branch. While we could work around this manually, this seems like rather an error-prone approach to take, as a result of which we’re still hunting for a better solution.
  • We have had issues with the Emma code coverage plugin and the production version of the Android Maven Plugin.
    In any case, the absence of branch coverage on Emma make it a non-starter in the first place.







Behaviour-Driven Development in .NET with SpecFlow and White

Mike Borozdin (mike.borozdin at cloudreach)


Introduction


This article gives a general overview of behaviour-driven development (BDD), talks about .NET tools for BDD (SpecFlow) and UI testing (White) and proceeds with a working example giving hands on BDD in .NET.

Behaviour-Driven Development (BDD) and Outside-in Development 


Behaviour-Driven Development (BDD) is a philosophy of software development where the focus, as the name suggests, is on implementing behaviour. First proposed by Dan North, this approach to development does away with a lot of the confusion — exemplified by questions like 'What do I test?', 'Where do I start testing?', and 'Where do I stop testing?' — that developers who set out to use TDD are faced with.

Outside-in development is a complementary technique that requires developers to focus primarily on defining customer requirements expressed as acceptance criteria, and work inwards towards building an implementation from there. BDD facilitates outside-in development by requiring the description of acceptance criteria as desired behaviours.

Let's take a look at a quick example. Consider the following user requirement:
As a user of this awesome application
I want to log in using my authentication credentials
So that not every Tom, Dick, and Harry can look at my precious data

One of the acceptance criteria for this story would be:
Given I am on the / page of the web application
When I enter my (awesome) authentication credentials
Then I should be presented with the home page

This criterion, written in plain English, describes the desired behaviour. This acts as an ideal starting point for us to write our acceptance tests. Once the acceptance tests have been written, a developer may then move inwards, writing integration and unit tests for the implementation that is required. It is important to note here that BDD does not end with the acceptance tests, but should be used throughout as we move inwards (see how Dan North suggests using shouldExhibitBehaviour(...) to describe tests rather than testExpectedFunctionality(...)).

Next, we show how to implement the outermost step of the BDD process in a .NET project. To do this, we use SpecFlow, a tool that allows you to translate acceptance criteria written in plain English into executable tests.

SpecFlow


SpecFlow translates human-language acceptance tests into runnable .NET code. What is even more interesting is that it is capable of generating test reports that can be understood by non-technical stakeholders like business analysts.

Acceptance tests (sometimes called scenarios in the literature) are specified in Gherkin, a plain text DSL that adds some semantics to plain English. An acceptance test describes a sequence of events in the form: Given [pre-condition], when [action], then [effect], when [another action], then [another effect], and so on. For example,

Given I am in the New Customer Form
When I leave the company name field blank
Then I should be presented with an error saying so
Here's a more complex example with multiple actions:
Given I am in the Login Form
When I enter a valid e-mail in the e-mail field
When I enter a valid password in the password field
Then I should see the Dashboard window

Testing Desktop UIs with White


As an acceptance test describes behaviours that are visible to the end-user, they typically require a means of instrumenting interactions with the application's UI; this allows you to automate actions like clicking on buttons, filling in text fields, and searching for displayed text.

In this post, we describe the use of White, a UI testing tool that allows you to automate interactions with desktop applications written in .NET (WPF and WinForms), as well as native Windows applications.

Working Example


Let's use SpecFlow and White to write a simple desktop application. 

Stories and Acceptance Criteria


The example application we shall look at in this post is a simple app that takes a customer's details and saves it to a database.

To start us off, our business analyst has provided us with this story,

Feature: Saving Customer Information

As a sales manager
I want to save a customer’s details
So that I can contact them later

and these acceptance criteria.

Scenario: HappyPath

Given I am in the New Customer window
When I enter a company name in the company name field
When I enter a contact e-mail address in the e-mail field
When I click on the Next button
Then I should see a newly added customer in the list of customers filed by their company name

Scenario: Blank Company Name
Given I am in the New Customer window
When I leave the company name field blank
When I click on the Save button
Then I should be presented with an error saying so

These criteria are not exhaustive, but should suffice for the purposes of this post.

Installing SpecFlow and White


SpecFlow is available on NuGet. However,  at the time of this going to the metaphorical press, the latest version of White isn't. You can work around this by downloading the White assemblies and then adding references to White.Core.dll and White.NUnit.dll.

When writing acceptance tests, it is a good idea to isolate them from the code under test by creating a separate class library project in your Visual Studio solution.

Gettings Started with SpecFlow


The acceptance criteria as well as the user story definition go into a SpecFlow feature file. You can create one on Visual Studio (Add-> New Item -> SpecFlow Feature file). SpecFlow feature files may contain an arbitrary number of acceptance tests. Moreover, acceptance tests for the same feature can be split across multiple feature files.

A SpecFlow step definition file that is used to instrument your tests is generated whenever you create a SpecFlow feature file. This is where you specify the instrumentation that allows you to perform the actions described using your DSL.

You can use the stub below to write your own SpecFlow step definition file for the acceptance criterion described in our example.
[Binding]
public class SavingCustomerInformation
{
    [Given("I am in the New Customer window")]
    public void GivenNewCustomerWindow()
    {
    }

    [When("I enter a company name in the company name field")]
    public void WhenEnterCompanyName()
    {
    }

    [When("I enter a contact e-mail address in the e-mail field")]
    public void WhenEnterEmail()
    {
    }

    [When("I click on the Save button")]
    public void WhenClickSaveButton()
    {
    }

    [Then("I should see a newly added customer in the list of customers filed by their company name")]
    public void ThenNewCustomerInList()
    {
    }

    [When("I enter a company name that has been already added in the company name field")]
    public void WhenEnterExistingCompanyName()
    {
    }

    [Then("I should be presented with an error saying so")]
    public void ThenError()
    {
    }

}
The snippet given below is a plain piece of C# code, the only interesting bit are the special annotations [Given], [When], and [Then] that specify that the annotated method will be executed upon running a statement declared in the annotation.

White to the Rescue


It is reasonable to expect that such a method should perform UI manipulations such as populating forms and clicking on buttons. Working with White starts with launching or attaching to an existing process of an application we want to test.

Application applicationUnderTest = Application.Launch(pathToApplication);

Every acceptance tests of ours has the same pre-condition block:
Given I am in the New Customer window

That translates into finding an appropriate window:
//the window object will be used in many methods, so it is reasonable to make it a member variable
private Window newCustomerWindow;

[Given("I am in the New Customer window")]
public void GivenNewCustomerWindow()
{
    this.newCustomerWindow = SavingCustomerInformation.applicationUnderTest.GetWindow("New Customer");
}

Our scenarios also involve populating some fields which can be also easily done with White. Essentially, when you need to manipulate any control with White you first find it by either its name or any other criteria and they you perform manipulations on it. The two methods below illustrate this technique applied to writing in a text field and clicking on a button.
[When("I enter a contact e-mail address in the e-mail field")]
public void WhenEnterEmail()
{
    TextBox emailTextBox = this.newCustomerWindow.Get<TextBox>("emailTextBox");
    emailTextBox.Enter("some@email.com");
}

[When("I click on the Save button")]
public void WhenClickSaveButton()
{
    Button saveButton = this.newCustomerWindow.Get<Button>("saveButton");
    saveButton.Click();
}

Putting It All Together


Speaking about some certain aspects of using SpecFlow and White, it is still necessary to have an entire picture of the whole testing suite, that is given below.

[Binding]
[Binding]
public class SavingCustomerInformation
{
    private static Application applicationUnderTest;
    private Window newCustomerWindow;
    private const string COMPANY = "Some Company";

    [BeforeFeature]
    public static void LaunchApplication()
    {
        SavingCustomerInformation.applicationUnderTest = Application.Launch(@"..\..\..\Application\bin\Debug\Application.exe");
    }

    [Given("I am in the New Customer window")]
    public void GivenNewCustomerWindow()
    {
        this.newCustomerWindow = SavingCustomerInformation.applicationUnderTest.GetWindow("New Customer");
    }

    [When("I enter a company name in the company name field")]
    public void WhenEnterCompanyName()
    {
        TextBox companyTextBox = this.newCustomerWindow.Get<TextBox>("companyTextBox");
        companyTextBox.Enter(COMPANY);
    }

    [When("I enter a contact e-mail address in the e-mail field")]
    public void WhenEnterEmail()
    {
        TextBox emailTextBox = this.newCustomerWindow.Get<TextBox>("emailTextBox");
        emailTextBox.Enter("some@email.com");
    }

    [When("I click on the Save button")]
    public void WhenClickSaveButton()
    {
        Button saveButton = this.newCustomerWindow.Get<Button>("saveButton");
        saveButton.Click();
    }

    [Then("I should see a newly added customer in the list of customers filed by their company name")]
    public void ThenNewCustomerInList()
    {
        ListBox customersList = this.newCustomerWindow.Get<ListBox>("customersListView");

        Assert.NotNull(customersList.Items.Find(x => x.Text == COMPANY));
    }

    [When("I leave the company name field blank")]
    public void WhenLeaveBlankCompanyName()
    {
        TextBox companyTextBox = this.newCustomerWindow.Get<TextBox>("companyTextBox");
        companyTextBox.Enter(string.Empty);
    }

    [Then("I should be presented with an error saying so")]
    public void ThenError()
    {
        Assert.NotNull(this.newCustomerWindow.Get(SearchCriteria.ByText("Company name is empty")));
    }

    [AfterFeature]
    public static void KillApplication()
    {
        SavingCustomerInformation.applicationUnderTest.Kill();
    }
}

Having the whole acceptance test code at a glance, it is evident that actual testing occurs in methods annotated with [Then]. Such methods contains Assert expressions and it is possible to make use either MSTest or NUnit.

Methods that have attributes of [BeforeFeature] and [AfterFeature] are executed before and after a feature respectively. In the code snippet above, such methods are used for launching and killing the application. Since the methods carrying such annotations are required to be static, the member variable containing a reference to the application under test is also declared as static.

Running your Tests


Since SpecFlow tests are compiled into DLL files, it is not possible to run them on their own. There are multiple tools that can do this for you, ranging from the built-in in Visual Studio MSTests to SpecRunner, which comes as a separate dependency in NuGet, and NUnit.

SpecRunner produces neat and most human readable HTML reports, while NUnit allows you to run individual scenarios. However, when using NUnit, you should bear in mind that the [BeforeFeature] annotation behaves like [BeforeScenario]. Thus, if you are launching an application under test in such methods, it will be executed on each acceptance test instead being run once for all the tests of a given user story.

If you'd like to switch runner, you can either go to Tools -> Options -> SpecFlow -> General -> Test Runner Tool or just modify app.config file of a test project. If you want to use NUnit as a runner, then the only option is modifying app.config, as NUnit is not present in the Tools drop-down menu.
<specflow>
    <unittestprovider name="NUnit">
</unittestprovider>
</specflow>

More SpecFlow Goodies


SpecFlow step definition annotations can also use regex matching, thereby allowing you to pass parameters into generic step definitions. For example, instead of simply stating:
When I enter a company name in the company name field

You can write:
When I enter ‘Acme Ltd.’ in the company name field
Then I should see a message saying ‘A new company has been added’
And then receive these parameter values in your code:
[When("I enter ‘(.*)’ in the company name field")]
public void WhenEnterCompanyName(string companyName)
{
    TextBox emailTextBox = this.newCustomerWindow.Get<TextBox>("emailTextBox");
    emailTextBox.Enter(companyName);
}

[Then("I should see a message saying ‘(.*)’")]
public void ThenEnterCompanyName(string message)
{
    Assert.NotNull(this.newCustomerWindow.Get(SearchCriteria.ByText(message)));
}
Of course, it’s not necessary to have acceptance test written in this way, as it might make them brittle and less robust, but it’s nice to have such an opportunity, just in case.

Now Write Some Code for Your Application


If you were to run your tests now, they would fail (or to be precise, they'd throw an exception as the application to test still doesn't exist). That is not a problem, as the whole point of TDD is to use your tests  to guide your code. You can now write your code (writing any tests that may entail first), writing just enough code to make the tests pass.

You can download all of the source code for the example application, including the tests and the application, here.
Pontus is ready and waiting to answer your questions