architects-and-agile

August 1st, 2010 No comments

This was just a nice little presentation from infoq on agilists and architects that I made some notes on.

Architects:

Enterprise, Data, Technical, Integration Architects: usually disconnected from the application (cf application architect)
– shared across business unit or development stream
– against reckless proliferation of tools
– often charged with stability

How does self-empowered teams work with enterprise standards and reviews?

Even good people have been messed up by bad ideas. What is in agile for architects?
– transparency and visibility into progress
– up to date specification of functionality (through tests and also self checking)
– results in adaptable code (reuse/harvest after the fact rather than planned)

How to make it work?
– Architects as customers
– Architects as team members … means they are customers and techies

Architects are centrally to understanding how all the business holds together and can help with technical debt

Making estimates based on clean code and that on legacy code

Categories: Uncategorized Tags:

a-quick-note-on-brooks

August 1st, 2010 No comments

Accidental and essential complexity in software

Brooks said that he believed the hard part of building software to be the specification, design and testing of the conceptual construct of software, not the labour of representing it, and testing the fidelity of that representation.

This is not surprising that in the shift from writing software to building software that we have separated out design from building, building from testing and testing from design. This process we would call waterfall and often we see people having a single-pass version in their mind’s eye.

Iterative and incremental is a shift from building software to growing software. That is, first make the system run and that add to it bit by bit while always keeping it a working system. Brooks points out that he finds that teams can grow much more complex entities in four months than they can build.

Categories: Uncategorized Tags:

gerald-mezaros-concept-to-backlog

August 1st, 2010 No comments

Notes from Gerald Mezaros on Concept to Backlog

I was just re-reading Gerald Mezaros of the xunittestpatterns from his pdf of from concept to backlog
and also having a look at his presntation on infoq.

I was using him to think through an approach with a client. These are my notes from a while back.

The client

The current situation is:

– that the product has gone to business case
– there are a list of major features and put into themes
– overall costing/effort estimates
– business staffing/engagement with vendors (skills list)
– end delivery date

We already have:
– existing product (architecture, infrastructure)
– set of tests/test strategy based on the test automation pyramid (fitnesse, selenium, nunit)

There is no:
– is there really a product design?
– release plan
– no user stories
– no story tests/acceptance criteria

Risks:
– is time going to be an issue with new features?
– will the existing architecture still hold?
– what the introduction of new platform (eg Sitecore)
– integration tests take 15 minutes to run (aka functional tests layer)

Notes from the talk

BDUF vs LRM (last responsible moment)
– making better decision later

Product Envisioning
Product Planning
Product Execution

Elevator Statement (Moore – Crossing the Chasm)

For (target customers)
who are dissatisfied (with current alternatives)
our product is a (new product category)
that provides (key problem-solving capabilities)
unlike (the product alternativ)
we have assembled (key “whole prodct” for features for our specific application)

Tensions:

- just in time analysis so that we don’t have inventory as waste

What have we done in our current project?

Main Features -
Need:
– product design (eg screens, data models or messaging protocols – not software design) – barely sufficient to something the customer loves
– product behaviour (featurs and definition of scope)

We have:
– some high level architecture (dotnet, test strategy)
– do we need more of components?

What about a release plan?
– date & features

Do we want use cases are deliverables of the project (yes – current implementation has)

Release Planning: (manage scope to fit budget)
– needing priorities around user stories (allow us some wiggle room)
– we have committed to the features, what about the stories? (that we don’t have)

Categories: Uncategorized Tags:

subversion-conventions-notes

August 1st, 2010 No comments

Moving to Subversion notes:

I have included my copy of the pragmatic programmers (PP) Subversion book. Everything I would suggest is covered well enough in this book and I will refer to pages in this. I have also attached the free svn red book from oreilly.

My assumption in these notes is that you haven’t used SVN or are familiar with its strategies. In perforce, you have been using a mainline strategy (as documented in the wiki). Subversion does not use this strategy. You will need to get familiar with its approach. PP p54 says:

“Developers should use branches to separate the main
line of development from code lines that have dif ferent
life cycles, such as release branches and major code
experiments. Tags are used to identify signiï¬cant points
in time, including releases and bug ï¬xes.”"

Access to the repository:

For read-only browsing access in a browser this will allow you to look at all the projects.

  • https://domain/svn/

For real work, checking out and committing with an SVN client:

  • https://domain/svn/project/trunk

SVN Clients:

  • TortoiseSVNGUI integration into explorer – http://tortoisesvn.net/downloads
  • AnkhSVN – integration into Visual Studio – http://ankhsvn.open.collab.net/
  • VisualSVN – integration into Visual Studio – http://www.visualsvn.com/visualsvn/
  • SVN commandline – http://subversion.tigris.org/getting.html#windows

Personally, I use tortoise and commandline and then also visual studio integration.

Checking out:

Everyone has their own naming conventions. Personally, when dealing with a trunk, I often check to a folder name with hyphen trunk in it. The name of the folder isn’t that important in the long run because it can be renamed.

 cd /path/to/src
 svn co https://domain/svn/project/trunk project-trunk

Committing:

svn commit -m "my check in" (PP p.91)

But, note that you will have already need to have added a file. GUI client will help with this.

Adding might look like this in the command line: svn add . (PP p.63)

Organising the repository

  1. There are also three folders for each project trunk, tags, branches (PP p.108)
  2. We will NOT be running a multiple project repository because we will be using multiple repositories when needed (PP p.110)
  3. Repositories can be linked via svn:externals when and if needed (PP p.135)

Using tags and branches

This is all covered in Chapter 9 (PP p.111) including creating release branches, fixing bugs, etc.

Naming conventions

My suggestion is to use PP conventions (p. 114)

Thing to Name     Name Style            Examples 
Release branch    RB-rel                RB-1.0 
                                        RB-1.0.1a 
Releases          REL-rel               REL-1.0 
                                        REL-1.0.1a 
Bug fix branches  BUG-track             BUG-3035 
                                        BUG-10871 
Pre-bug fix       PRE-track             PRE-3035 
                                        PRE-10871 
Post-bug fix      POST-track            POST-3035 
                                        POST-10871 
Developer experiments TRY-initials-desc TRY-MGM-cache-pages 
                                        TRY-MR-neo-persistence
Categories: Uncategorized Tags:

perforcemigration-notes

August 1st, 2010 No comments

Instructions:
http://www.perforce.com/perforce/doc.current/user/p4perlnotess.txt

But, actually:

% wget ftp://ftp.perforce.com/perforce/r09.1/bin.tools/p4perl.tgz (extract to /path/to/tmp/p4perl)

extract to location /path/to/tmp/

Get:

wget ftp://ftp.perforce.com/perforce/r09.1/bin.darwin80u/p4api.tgz (extract to /path/to/tmp/p4api)

wget ftp://ftp.perforce.com/perforce/r09.1/bin.darwin80u/p4

extract to location
/path/to/tmp/

p4 todd$ ls
p4 p42svn.pl p4api p4api.tgz p4perl p4perl.tgz

cd p4perl

perl Makefile.PL –apidir ../p4api (from p4api.tgz)
make

make tests
sudo make install

Password:

% perl -MP4 -e “print P4::Identify()”

Perforce – The Fast Software Configuration Management System.
Copyright 1995-2009 Perforce Software. All rights reserved.
Rev. P4PERL/DARWIN9X86/2009.1.GA/205670 (2009.1 API) (2009/06/29).

Right now I am ready to do the migration: (I used version 91)

wget http://p42svn.tigris.org/source/browse/*checkout*/p42svn/trunk/p42svn.pl?revision=91

% perl p42svn.pl usage

If you get errors then you have installation problems with perl and spent time sorting it out. (I had major problems that took me a couple of hours to sort out including updating, upgrading, installing, arrrggghhh)

perl p42svn.pl –user yours –password secret –port xx.xx.xx.xx:1666 –branch “//depot/project”=trunk > svn.dump

Now, move that file to the windows box

Backon the windows box:

svnadmin create c:\Repositories\project
svnadmin load c:\Repositories\project < svn.dump

Categories: Uncategorized Tags:

jquery-bdd

August 1st, 2010 No comments

Notes from a jQuery session

Structure of session:

  • Jump into an example
  • Build some new functionality
  • Come back and see the major concepts
  • Look at what is actually needed to treat javascript as a first-class citizen
  • Different testing libraries

Quick why a library in javascript?

  • cross-browser abstraction (dynduo circa 1998 was still hard!)
  • jQuery, MooTools, Extjs, Prototype, GWT, YUI, Dojo, …
  • I want to work with DOM with some UI abstractions – with a little general purpose
  • simple HTML traversing, event handling
  • also functional, inline style
  • I want plugin type architecture

Story plugin demo

  • Viewer of StoryQ results
  • StoryQ produces XML, this widget gives the XML a pretty viewer

A screenshot and demo

What would your acceptance criteria be? What do you think some of the behaviours of this page are?

Acceptance:

eg should display the PROJECT at the top with the number of tests

Behaviours:

think in terms of themes: data, display, events

The tests … what does the application do?

  • run the tests and see the categories
  • data loading: xml
  • display: traversing xml and creating html
  • events: click handlers

Let’s build some new functionality!

Goal: add “Expand All | Contract All | Toggle” functionality to the page

Acceptance:

  • The user should be able to expand, collapse or toggle the tree

Specs

Display:
* should show “Expand All | Contract All | Toggle”
Events:
* should show all results when clicking expand all
* should show only top class when clicked contract all
* should toggle between all and one when clicking on toggle

Coding: Add acceptance

Add Display specs

Add Event specs

Return back to completing the Acceptance

Major aspects we covered

HTML traversing

  • I want to program akin to how I look at the page
  • I may look for: an element, a style, some content or a relationship
  • then perform an action
$(‘div > p:first’)
$(‘#mylist’).append(“
  • another item
  • “)

    Event handling

    • I want to look at page and add event at that point
    • I want to load data (ie xml or json)
    $(‘div’).click(function(){
    alert(“div clicked”)
    })
    $(‘div’).bind(‘drag’, function(){
    $(this).addClass(‘dragged’)
    })
    $(‘#results’).load(‘result.html’)
    $.get(‘result.xml’, function(xml){
    $(“user”, xml).each(function(){
    $(“
  • “).text($(this).text() .appendTo(“#mylist”))
    })
    })

    Functional style

    • almost everything in jQuery are JQuery objects
    • that returns an object
    • every method can call a jQuery object
    • that means you can chain
    • plus I want it to be short code

    $(‘‘)
    .addClass(‘indent’)
    .addClass((idx == 4) ? ‘scenario’ : ”)
    .text($(this).attr(‘Prefix’) + ‘ ‘ + $(this).attr(‘Text’))
    .append($(‘‘).text(“a child piece of text”)
    .click(function(){ $(this).addClass(‘click’)}))
    .appendTo(results)

    Plugin architecture

    • drop in a widget (including my own)
    • then combine, extend
    • help understand customisation
    • basically just work

    $(‘#tree’).treeview();
    $.ajax({
    url: ‘/update’,
    data: name,
    type: ‘put’,
    success: function(xml){
    $(‘#flash’).text(“successful update”).addClass(‘success’)
    }
    })

    With power and simplicity … comes responsibility

    • the need to follow conventions
      – plugins return an array
      – plugins accept parameters but have clear defaults
      – respect namespace
    • the need for structure
      – test data
      – min & pack
      – releases
    • the need to avoid mundane, time consuming tasks
      – downloading jquery latest
      – download jQuery UI
      – building and releasing packages
    • needs tests
      – I use jsspec

    Sounds like real software development?

    Treat javascript as a first-class citizen

    Give your plugin a directory structure:

    /src
    /css
    /images
    query.plugin.js
    /test
    spec_plugin.js
    acceptance_plugin.js
    specs.html
    acceptance.html
    /lib
    /jsspec
    jquery.min.js
    jquery-ui.js
    /themes
    /base
    example.html
    Rakefile
    History.txt
    README.txt

    Generate your plugin boilerplate code

    jQuery Plugin Generator
    * gem install jquery-plugin-generator

    (function($) {
    $.jquery.test = {
    VERSION: “0.0.1″,
    defaults: {
    key: ‘value’
    }
    };

    $.fn.extend({
    jquery.test: function(settings) {
    settings = $.extend({}, $.jquery.test.defaults, settings);
    return this.each( function(){
    self = this;
    // your plugin

    })
    }
    })
    })(jQuery);

    Use a build tool to do the … ah … building

    rake acceptance # Run acceptance test in browser
    rake bundles:tm # Install TextMate bundles from SVN for jQuery and…
    rake clean # Remove any temporary products.
    rake clobber # Remove any generated file.
    rake clobber_compile # Remove compile products
    rake clobber_package # Remove package products
    rake compile # Build all the packages
    rake example # Show example
    rake first_time # First time run to demonstrate that pages are wor…
    rake jquery:add # Add latest jquery core, ui and themes to lib
    rake jquery:add_core # Add latest jQuery to library
    rake jquery:add_themes # Add all themes to libary
    rake jquery:add_ui # Add latest jQueryUI (without theme) to library
    rake jquery:add_version # Add specific version of jQuery library: see with…
    rake jquery:packages # List all packages for core and ui
    rake jquery:packages_core # List versions of released packages
    rake jquery:packages_ui # List versions of released packages
    rake jquery:versions # List all versions for core and ui
    rake jquery:versions_core # List jQuery packages available
    rake jquery:versions_ui # List jQuery UI packages available
    rake merge # Merge js files into one
    rake pack # Compress js files to min
    rake package # Build all the packages
    rake recompile # Force a rebuild of the package files
    rake repackage # Force a rebuild of the package files
    rake show # Show all browser examples and tests
    rake specs # Run spec tests in browser

    Testing … acceptance and specs

    • specs: BDD style – DOM traversing and events
    • acceptance: tasks on the GUI with the packaged version (minified or packed)
    • these both server as good documentation as well
    • plus, you have demo page baked in!

    Compiling and packaging

    • Compiling javascript … hhh? … yes, if you minify or pack your code
    • gzip compression with caching and header control is probably easier though
    • packed code is HARD to debug if it doesn’t work

    Now you are ready for some development

    Different ways to test Javascript

    Understanding JavaScript Testing

    • testing for cross-browser issues – so this is useful if you are building javascript frameworks
    • Unit – QUnit, JsUnit, FireUnit,
    • Behvaiour – Screw.Unit, JSSpec, YUITest,
    • Functional with browser launching – Selenium (IDE & RC & HQ), Watir/n, JSTestDriver, WebDriver
    • Server-side: Crosscheck, env.js, blueridge
    • Distributed: Selenium Grid, TestSwarm

    Reference

    jQuery CheatSheet

    • slide 48: great explanation of DOM manipulation – append, prepend, after, bfore, wrap, replace …
  • Fluent Configurator – thoughts on getting a design

    March 14th, 2010 No comments

    In a previous post series I wrote about Configuration DSLs – I’m now just looking at this from another angle of going back to some reading about the microsoft mechanism itself.

    A quick note about the previous approach. The configuration is centralised into one Configuration object and then the application has this available. This is similar to Microsoft approach because we have ConfigurationManager available everywhere. The problem for me is that with ConfigurationManager the central configuration point is the app.config and that is how developers expect the application to work – working against such conventions is often creates more friction than is necessary.

    Therefore, if you can’t use a (replace the) central configuration object as above, you need to have multiple xml settings. But how? Microsoft has a design time changer – the app designer. AFAIK this works when you deploy from your design environment. That is far from ideal and means that you create a build per environment. I often see this often or something that approximates this approach. But it does not lend itself to a build server. Here’s a well documented approach that can work in both design and deploy time with some adjustments as this one is design time only and we would need to implement the same code in the deploy.proj for msbuild

    So the next approach which I have used is to update through xml replacements. This is easiest done replacing entire xml files which are includes into the main xml file. This can be done easily at deploy time. The problem is that all environment settings are shipped. In the situation where the package is for the one client – this isn’t actually a problem. The question is the switching mechanism to swap over xml files. There is the other issue of reconciling differences between environment settings.

    This leads to a solution of having all settings in the same file. This approach is outlined in Creating Custom Configuration Section which I mentioned below. This approach could work well for the settings in your application. For example, using a proxy, I hook this up myself with my WebRequest. However, this approach wouldn’t work for log4net settings. So, we still need a better approach for specifying settings in different environments.

    Where I want to head is to write a wrapper that manages writing out the xml from C# configuration. This would allow a management strategy that works with the current approach, but could also work in the first mode too of providing its own configuration references. Because settings are in C# they are hidden unless needed. Using an approach like migratordotnet we interrogate the dll for the settings and make updates at deploy time. This interrogation can take the form of dry-run, diffs, updates, backups.

    Configuration is a complex and has many views. All those view combined often leads to mistakes so we need it to be as simple as possible. Very simple approaches have often resulted in cut-and-paste management – I think this is simplistic and error prone. As a developer, I understand that for my application I need a way to extend my reach into the production environment and yet give operations enough control for customisation. Because I certainly don’t want to do overnight support, nor do I want to know the credentials for production systems.

    There is a final issue. How do we know what environment we are in? (and what are these called? – local, build, test, prod) Given windows conventions and mixed in with a little *nix I would go with this:

    • System environment variable – in C# accessed through a registry key and batch (eg set APP_ENV=Prod)
    • Process environment variable – eg passed in via commandline and used in say msbuild
    • machine.config
    • app/web.config – I would use this other than it has been update from one of the above (if you are using this it is likely that it was manually set)

    Note: I think that for enterprise type solutions (only one production deployment) we do know about every environment that we are deploying to. If not, these ideas are not for you because you have multiple deployments (customers). To me, this is consumer-type software and requires that installers can manage themselves.

    References

    [1] – General about ConfigurationManager

    If you want to learn about configuration then here is the key series by Jon Rista on The Code Project

    [2] – Creating custom configuration sections for environment

    • example to provide environment specific settings (dev through to prod)
    • implementation is for runtime switching
    • use a custom implementation of AppSettings
    • uses the machine.config for global settings
    • an approach that requires a specific implementation and xsd updates. Good example that the current implementation is limited and customisations are complex.
    • design time checking through xsd (rather than intellisense)

    [3] – using compile/deploy time switching

    [4] – design time deltas with deploy time switching

    [5] – poking files

    *
    • “XmlMassUpdate MSBuildCommunity Tasks”:
    • “XMLpoke in nant”
    • “XMLConfig”
    Categories: Uncategorized Tags:

    Fluent Controller MvcContrib – Part II – Coding the Controller Actions and Redirects

    March 7th, 2010 No comments

    In the last entry, we created designed our controller through a test:

    [Test]
    public void SuccessfulIndex()
    {
        GivenController.As&lt;UserController>()
            .ShouldRenderItself(RestfulAction.Index)
            .WhenCalling(x => x.Index());
    }
    

    Now, we need to code this:

    A Fluent Controlller in action

    In fact, to make test run above, you need to do nothing else than inherit from the AbstractRestfulFluentController.

    using MvcContrib.FluentController;
    
    public class UserController : AbstractRestfulFluentController
    {
        public ActionResult Index()
        {
            return View();
        }
    }	
    

    Let’s now look at how to create a skinny controller. Let’s take a redirection design:

    GivenController.As&lt;UserController>()
        .ShouldRedirectTo(RestfulAction.Index)
        .IfCallSucceeds()
        .WhenCalling(x => x.Create(null));
    

    Here’s the controller code we need:

    public ActionResult Create(object model)
    {
        return CheckValidCall()
            .Valid(x => RedirectToAction(RestfulAction.Index))
            .Invalid(() => View("New", model));
    }
    

    A more complex example of Create is where it calls a repository. Here if the Repository throws an exception it will execute .Invalid otherwise it will execute .Valid.

    public ActionResult Create(object model)
    {
        return CheckValidCall(() => UserRepository.Create(model))
            .Valid(x => View(RestfulAction.New, x))
            .Invalid(() => RedirectToAction(RestfulAction.Index));
    }
    

    So far you have seen two fluent controller actions available, however, also available are:

    • InvalidNoNewErrors
    • Other

    And within the context of CheckValidCall you also get access:

    • controller
    • model
    • isValid
    • newErrors

    Another feature to be aware of is that you can create own extensions. The current CheckValidCall returns a FluentControllerAction<T> so all you have to do is create an extension on this as you would with an extension method. You can even rewrite the CheckValidCall and create your own one.

    Fluent Controller MvcContrib – Part I – Designing Controller Actions and Redirects

    March 7th, 2010 No comments

    In an earlier post/03/test-automation-pyramid-asp-net-mvc/ I said that I unit test my controllers. What I didn’t say was that I (with most of the work done by my colleague Mark and field tested by Gurpreet) had write code to make this possible. To unit test our controllers we put a layer of code that was an abstraction for “redirections”. This has turned out to be very successful for the line of business applications we write. Mark coined this a fluent controller. Out fluent controller has these benefits:

    • test-first design of controller redirections
    • also isolate that the controller makes the correct repository/service calls
    • lower the barrier to entry by developer new to MVC
    • avoids a fat controller antipattern
    • standardises flow within actions

    I also tend toward a REST design in the application so we also wanted it to live on top of the SimlyRestful contrib. You’ll find there’s an abstract class both with and without simplyRestful. I will make a quick, unsubstantiated comment. The fluent controller does not actually help you create a controller for a REST application – it is Restful but really not a full implementation of REST.

    Designing Controller Actions

    In a simplyRestful design, the flow is standardised per resource. We have out 7 actions that we decide what is going to be implemented.

    Fluent Controller Action Redirects/Renders

    How to write it test first?

    In words, I have a User Controller that displays a user and I can do the usual CRUD functions. These examples are taken from the MvcContrib source unit tests

    This test, I enter in on Index and it should just render itself and I don’t need to pass anything in:

    using MvcContrib.TestHelper.FluentController;
    	
    [Test]
    public void SuccessfulIndex()
    {
        GivenController.As<UserController>()
            .ShouldRenderItself(RestfulAction.Index)
            .WhenCalling(x => x.Index());
    }
    

    Got the hang of that one? Here’s some ones that redirect based on whether or not the repository/service call was successful or not. This example, imagine, you have just said Create me the user:

    [Test]
    public void SuccessfulCreateRedirectsToIndex_UsingRestfulAction()
    {
    
        GivenController.As<UserController>()
            .ShouldRedirectTo(RestfulAction.Index)
            .IfCallSucceeds()
            .WhenCalling(x => x.Create(null));
    }
    
    [Test]
    public void UnsuccessfulCreateDisplaysNew_UsingString()
    {
        GivenController.As<UserController>()
            .ShouldRenderView("New")
            .IfCallFails()
            .WhenCalling(x => x.Create(null));
    }
    

    Here’s a test that ensures that the correct status code is returned. In this case, I will have done a GET /user and I would expect a 200 (OK) result. This is very useful if you want to play nicely with the browser – MVC doesn’t also return the status code you expect.

    [Test]
    public void ShowReturns200()
    {
        GivenController.As<UserController>()
            .ShouldReturnHead(HttpStatusCode.OK)
            .WhenCalling(x => x.Show());
    }
    

    The .ShouldReturnHead was a helper method, it actual delegated by to .Should which you too can use to write your own custom test helpers:

    [Test]
    public void GenericShould()
    {
        GivenController.As<UserController>()
            .Should(x => x.AssertResultIs<HeadResult>().StatusCode.ShouldBe(HttpStatusCode.OK))
            .WhenCalling(x => x.Show());
    }
    

    Now we can start combining some tests. In this case, we want to create a new customer and if it does, render the New view and ensure that ViewData.Model has something in it (and we could check that it is customer).

    [Test]
    public void ModelIsPassedIntoIfSuccess()
    {
        var customer = new Customer { FirstName = "Bob" };
    
        GivenController.As<UserController>()
            .ShouldRenderView(RestfulAction.New)
            .Should(x => x.AssertResultIs<ViewResult>().ViewData.Model.ShouldNotBeNull())
            .IfCallSucceeds(customer)
            .WhenCalling(x => x.Create(customer));
    
    }
    

    Sometimes, we only want return actions based on header location, so we can set this up first .WithLocation.

    [Test]
    public void HeaderSetForLocation()
    {
        GivenController.As<UserController>()
            .WithLocation("http://localhost")
            .ShouldReturnEmpty()
            .WhenCalling(x => x.NullAction());
    }
    

    There is also access to the Request through Rhino Mocks, try it like this.

    [Test]
    public void GenericHeaderSet()
    {
        GivenController.As<UserController>()
            .WithRequest(x => x.Stub(location => location.Url).Return(new Uri("http://localhost")))
            .ShouldReturnEmpty()
            .WhenCalling(x => x.CheckHeaderLocation());
    }
    

    test-automation-pyramid-asp-net-mvc

    March 6th, 2010 1 comment

    Test Automation Pyramid in ASP.NET MVC

    This is a reposting of my comments from Mike Cohn’s Test Automation Pyramid

    I often use Mike’s Test Automation Pyramid to explain to clients’ testers and developers how to structure a test strategy. It has proved the most effective rubric (say compared with the Brian Marick’s Quadrant’s model – as further evolved from Crispin and Gregory) to get people thinking about what going on in testing the actual application and its stress points. I want to add that JB Rainsberger’s talk mentioned above is crucial to understanding why that top level set of tests can’t prove integrity of the product by itself.

    It has got me thinking that perhaps that we need to rethink some assumptions behind these labels. Partly because my code isn’t quite the same as say described here am suggesting something slightly different than say this approach The difference of opinion in this blogs also suggests this. So I thought I would spend some time talking about how I use the pyramid and then come back to rethinking its underlying assumptions.

    I have renamed some parts of the pyramid so that at a first glance it is easily recognisable by clients. This particularly renaming is in the context of writing MVC web applications. I get teams to what their pyramid looks like for their project – or what they might want it to be because it is often upside down.

    My layers:

    • System (smoke, acceptance)
    • Integration
    • Unit

    I also add a cloud on top (I think from Crispin and Gregory) for exploratory testing. This is important for two reasons: (1) I want automated testing so that I can allow more time for manual testing and to emphasise that (2) there should be no manual regression tests. This supports Rainsberger’s argument not to use the top-level testing as proof of the systems integrity – to me the proof is in the use of the system. Put alternatively, automated tests are neither automating your tester’s testing nor are they a silver bullet. So if I don’t have a cloud people forget that manual testing is part of the automated test strategy (plus with a cloud when the pyramid is inverted it makes a good picture of ice cream in a cone and you can have the image of a person licking the ice cream and it falling off ;-) .)

    In the context of an MVC application, this type pyramid has lead me to some interesting findings at the code base level. Like everyone is saying, we want to drive testing down towards the Unit tests because they are foundational, discrete and cheapest. To do this, it means that I need to create units that can be tested without boundary crossing. For an asp.net MVC (just like Rails), this means that I can unit test (with the aid of isolation frameworks):

    • models and validations (particularly using ObjectMother)
    • routes coming in
    • controller rendering of actions/views
    • controller redirection to actions/views
    • validation handling (from errors from models/repositories)
    • all my jQuery plugin code for UI-based rendering
    • any HTML generation from HtmlHelpers (although I find this of little value and brittle)
    • any of course all my business “services”

    I am always surprised at how many dependencies I can break throughout my application to make unit tests – in all of these cases I don’t not need my application to be running in a webserver (IIS or Cassini). They are quick to write, quick to fail. They also require additional code to be written or libraries to be provided (eg MvcContrib Test Helpers).

    For integration tests, I now find that the only piece of the application that I still requires a dependency is the connection to the database. Put more technically, I need to check that my repository pattern correctly manages my object’s lifecycle and its identity; it is also ensuring that I correctly code the impedance mismatch between the object layer of my domain and relational layer of the database. In practice, this is ensuring a whole load of housekeeping rather than business logic: eg my migrations scripts are in place (eg schema changes, stored procs); my mapping code (eg ORM) and that the code links all this up correctly. Interestingly, I now find that this layer in terms of lines of code is less than the pyramid suggests because there is a lot of code in a repository service that can be unit tested – it is really only the code that checks identity that requires a real database. The integration tests left tend then to map linearly to the CRUD functions. I follow the rule, one test per dependency. If my integration tests get more complicated it is often time to go looking for domain smells – in the domain driven design sense I haven’t got that bounded context right for the current state/size of the application.

    For the top layer, like others I see it as the end-to-end tests and it covers any number of dependencies to satisfy the test across scenarios.

    I have also found that there are actually different types of tests inside this layer. Because it is web application, there is the smoke test – some critical path routes that show that all the ducks are lined up – selenium, watir/n and even Steve Sanderson’s MVCIntegationTest are all fine. I might use these tests to target parts of the application that are known to be problematic so that I get as earlier a warning as possible.

    Then there are the acceptance tests. This is where I find the most value not only because it links customer abstractions of workflow with code but also as importantly because it makes me attend to code design. I find that to run maintainable acceptance tests you need to create yet another abstraction. Rarely can you just hook up the SUT api and it works. You need setup/teardown data and various helper methods. To do this, I explicitly create “profiles” in code for the setup of data and exercising of the system. For example, when I wrote a Banner delivery tool for a client (think OpenX or GoogleAds) I needed to create a “Configurator” and an “Actionator” profile. The Configurator was able to create a number banner ads into the system (eg html banner on this site, a text banner on that site) and the Actionator then invoked 10,000 users on this page on that site. In both cases, I wrote C# code to do the job (think an internal DSL as a fluent interface) rather than say in fitnesse.

    Why are these distinctions important? A few reasons. The first is that the acceptance tests in this form are a test of the design of the code rather than the function. I always have to rewrite parts of my code so that the acceptance tests can hook in. It has only ever improved my design such as separation of concerns and it often has given my greater insight into my domain model and its bounded contexts. For me, these acceptance tests are yet another conversation with my code – but by the time I have had unit, integration and acceptance test conversations about the problem the consensus decision isn’t a bad point to be at.

    Second is that I can easily leverage my DSL for performance testing. This is going help me in the non-functional testing (or the fourth quarter of the Test Quadrants model).

    Third is that this is precisely the setup you need for a client demo. So at any point, I can crank up the demo data for the demo or exploratory testing. I think it is at this point that we have a closed loop: desired function specified, code to run, and data to run against.

    Hopefully, that all makes some sense. Now back to thinking about the underlying assumptions of what is going on at each layer. I think we are still not clear on what we really testing at each layer in the pyramid: most tend to be around the physical layers, the logical layers or the roles within the team. For example, some are mapping it to the MVC particularly because the V maps closely to the UI. Others are staying in a traditional unit, functional and integration partly because the separation of roles within a team.

    I want to suggest that complexity is a better underlying organisation. Happy to leave the nomenclature alone: the bottom is where there are no dependencies (unit), the second has one dependency (integration) and top have as many as you need to make it work (system). It seems to me that the bottom two layers require you to have a very clear understanding of your physical and logical architecture expressed in terms of boxes and directed lines ensure that you test each line for every boundary.

    If you look back to my unit tests it identified logical parts of the application and tested at boundaries. Here’s one you might not expect. The UI is often seen as a low value place to test. Yet, frameworks like jQuery suggest otherwise and breakdown our layering: I can unit test a lot of the browser code which is traditionally seens as UI layer. I can widgetize any significant interactions or isolate any specific logic and unit test this outside the context of the application running (StoryQ has done this).

    The integration tests tested across a logical and often physical boundary. It has really only one dependency. Because there is one dependency the nature of complexity here is still linear. One dependency equals no interaction with other contexts.

    The top level is all about putting it together so that people across different roles can play with the application and use complex heuristics to check its coding. But I don’t think the top level is really about the user interface per se. It only looks that way because the GUI is most generalised abstraction that we believe that customers and testers believe that they understand the workings of the software. Working software and the GUI should not be conflated. Complexity at the top-most level is that of many dependencies interacting with each other – context is everything. Complexity here is not linear. We need automated system testing to follow critical paths that create combinations or interactions that we can prove do not have negative side effects. We also need exploratory testing which is deep, calculative yet ad hoc that attempts to create negative side effects that we can then automate. Neither strategy aspires for illusive, exhaustive testing – or as JB Rainsberger argues – which is the scam of integration testing.

    There’s a drawback when you interpret the pyramid along these lines. Test automation requires a high level of understanding of your solution architecture, its boundaries and interfaces, the impedance mismatches in the movement between them, and a variety of toolsets required to solve each of these problems. And I find requires a team with a code focus. Many teams and managers I work with find the hump of learning and its associated costs too high. I like the pyramid because I can slowly introduce more subtle understandings of the pyramid as the team gets more experience.

    PostScript

    I have just been trawling through C# DDD type books written for Microsoft focussed developers looking for the test automation pyramid. There is not one reference to this type of strategy. At best, one book .NET Domain-Driven Design with C#: Problem – Design – Solution touches on unit testings. Others mention that good design helps testability right at the end of the book (eg Wrox Professional ASP.NET Design Patterns). These are both books that are responding the Evans’ and Nilsson’s books. It is a shame really.