In my last post I introduced the concept of a Test Persona – a software pattern for building acceptance tests that encapsulate the activities of an indivdual user of the system. I showed that acceptance tests could be refactored so that step definitions are defined in terms of actors in the system, rather than imperative bullet points. In this post, I introduce the pattern of Persona Focussed Testing.

Test Personas can be composed of strategies

Consider using test personas to trigger conversations around the actions and experiences of users that might not be otherwise be easily be apparent when implementing the tests. For instance, we could rewrite the acceptance criteria from the first blog:

Given I am a price-conscious customer
When I purchase an item that is sourced from my country
Then I will have chosen the 'free delivery' delivery option
And I will have paid $0.00 for delivery

The difference here is that we are simulating user behaviour, rather than specifying the appearance or process for purchasing/choosing delivery options.

The idea here is to only expose access to resources that a given persona has. For instance, I wouldn’t expect a customer to have access to, say, the inventory system, or the shipping manifests. But emails are definitely things a customer would have access to, along with their fax machine, their delivery address, their credit card, etc.

In my next post, I’ll talk about some tentative uses of test personas in defining a good customer experience.

Test Persona is a software pattern for acceptance tests. The use of this pattern leads to a de-coupling of test motivation from test implementation. Using test personas in acceptance tests is part of building a rich test domain. This pattern is complementary to other patterns that focus on the test domain, such as the page object pattern.

Concept

A test persona has knowledge of the actions and information available to a particular actor in a system under test. Acceptance tests interact with the test persons to accomplish activities that would normally be performed

Example

Here is a typical gherkin acceptance test

Given I am a customer
When I am about to purchase an item that can be sourced in my country
Then the cheapest price should include 'free delivery' as a delivery option

Most natural language based test harnesses will require a developer to implement a mapping into structured code. For instance, using page objects and some implicit web steps

At the moment I’ve haven’t gone any further with this, and I’m sure there’s a way of binding variables into the remote context more consisely. As it is, you have to remember to keep your locals declaration in sync with the values being pushed.

If I were to go to the next step, I’d probably try to remove that need to keep local names in sync. I guess it would look something like this:

Much to my suprise, Powershell holds up as a decent, testable language, with a few idiosyncrasies.

So far, I’ve been able to refactor Powershell to make use of its pervasive stream handling, and there are some useful tricks that can make Powershell look like other functional-style languages you know and love ( ruby, scala, LINQ, etc).

There are some nifty aliases:

? { test } |
% { process; result } |
% { process_result; finish}

? is an alias for ‘where-object’
% in an alias of for-each.

More syntactic strangeness

@{}

creates an empty hashmap, but

@[]

wraps things into a list context. You’ll notice that when the following expression doesn’t work like you’d expect:

Silverlight.App.IntegrationTests – contains tests that connection to the web, database, are asynchronous, etc

Silverlight.App.IntegrationHost – a ASP.NET project that will run the IntegrationTests

UnitTests and IntegrationTests are created with the Silveright UnitTesting project templates. These templates cause a test page to be created. The test page basically listens to events from the TestRunner (embedded in the Test silverlight applications), and presents it as (fiddly) HTML.

Our UnitTest project hasn’t changed much since we started. We have had issues with the IntegrationTests project:

Security

Code transparency – All application logic is marked as “Transparent”, which means that may call but may not extend or override “SafeCritical” or “CriticalCode”. The System.Net.WebClient is marked as SafeCritical. This means that you won’t be able to Mock/Stub WebClient. At all.

Internal event constructors – The constructor for DownloadStringAsyncCompleteEventArgs is internal; You won’t be able to simulate a WebClient completing an http request.

Silverlight applications loaded from the file system just plain cannot connect to web resources. There is no security policy that will allow it.

All of the above issues drove us to use the IntegrationHost to run the IntegrationTests, but in a web context. This is quite good, especially for within-IDE testing, since you can host your test data as flat files or as ASP driven test data in the same host.

Continous Integration

For the unit tests, we found a powershell script that will spawn IE and scrape the results into a file

For the integration tests, we modified the powershell script to spawn a WebDev.WebServer.exe against the IntegrationHost

The IntegrationTest xap file that is linked from the IntegrationHost will not get automatically deployed by msbuild – we use a copy task to pull it before launching IE.

Visual Studio wants to put the hosted xap file in ClientBin of the IntegrationHost. This is fine, but it also wants to put it into source control, which is not. Eventually, you’ll get the right combination of check-ins, deletes, et. al. and it won’t be an issue. Expect to lose a few hours on this.

The Law of Demeter (paraphrased as “Tell, Don’t Ask”) is the developer equivalent of an early morning stretch. If you wake up stiff and sore, running through a few gentle stretches can tease out some of the muscles that have been under too much load, and make you feel limber again.

Recently, I’ve been a bit of a one-trick pony when it comes to writing code – I just say “use the Law of Demeter” and expect people to know where I’m going. I think that’s a bit harsh (especially on my colleagues), so I’d like to mumble a few words about how it can work in practice.

I’ve also had pub-code conversations around this, and for people who use Demeter on a regular basis, the question is where do you stop? I think I’ll show my answer to this, but first:

The scenario:
We have various components in our system, and we want to generate a health check page that can help production support quickly diagnose high severity failures. All we need to do is generate a web page for those components…

The setup:
We have an old-school MVC web app – We use a templated view, our view Model is a hierarchy name/value pair structure called “ViewData”, and we’re using Typed Constructor Dependency Injection.

The inline HealthReport encapsulates the mapping to the View, and tells it what to render

The benefits:

It’s MUCH easier to unit test – the full range of health behaviour can be simulated now

Each Health has to only worry about Health, not how that will be represented

Adding more entries to the HealthReport is straightforward, and done in the object container

The interesting:

The name of “HealthReport” makes things clearer, and allows view abstraction (e.g. using a JmxHealthReport)

This seems a mix of object-oriented and functional code, albeit with some mutable state

Using enums (e.g. HealthStatus) rather than primitives allows more refactoring options, since it is straightforward to push behaviour (the ‘tell’) into the enum

The introduction of HealthReport helps to crystalise where the “action” is. I think there may be a general case here – that in practice, modelling the interaction between objects will often drive out a new object encapsulating that interaction.

When a Boy kisses a Girl – the kiss itself is important

When money is transferred from a source account to destination account – the payment itself is important