Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Acceptance Testing – "Under the Skin" or using Stubs, is that Okay?

From Why and When to Use Mock Objects, Mike Bria asks:


…So, my thought (and question) is this: is it okay for me to apply “faking” principles at a service level? In other words — I’m testing service 1, which, among a bunch of other little details, queries service 2 and posts a command to service 3. Can my test fake Service 2 & 3 and still be a valid Acceptance (or, what I prefer to call “Service”) test?

My opinion is yes, and we’ve done this ourselves to great effect in a certain situation earlier this year.  More importantly, I talked it over with a couple of our senior testers and they agreed with some caveats – you should only do this with particularly troublesome services, and you absolutely have to do some level of end-to-end blackbox testing.  The experience with the blackbox testing should be used to fine tune the whitebox tests that use the stubs to create more realistic tests.


Our Experience


Earlier this year my team built a new NT service to manage an asynchronous workflow between our large application, a brand new web service being built by a third party, and our backend messaging broker.  The messaging broker on the backend is notoriously difficult to work with, and we didn’t have any clean way to test the results inside the broker.  The 3rd party web service wasn’t ready.  In this case, we wrote a FitNesse DoFixture to simulate the interaction of our new service with its service dependencies.  We started the inner service controller class and used StructureMap to inject stub implementations of both the gateway interfaces to the 3rd party web service and the messaging broker.  It was undeniably successful.  Our tester was easily able to setup a wider range of failure conditions and edge cases in the interaction with the external dependencies.  We could simulate one of both of the dependencies being unreachable, or throwing exceptions on invocation to test the error handling of our service.  Most importantly, when we did attach the new service to the external dependencies for real it worked like a charm.


Testing User Interfaces “Under the Skin”


This might not be as true today as it was a couple years ago, but the conventional wisdom in Agile testing circles is to test user intefaces just “under the skin.”  In other words, bypass the actual user interface and test against the controller layers first, then use manual testing against the full UI.  The easiest way to enable that strategy that I know of is to use the Model View Presenter pattern to write ultra thin views that can be replaced in tests.  An easy way to go about this is to write a FitNesse DoFixture class to test a single screen, and make the DoFixture class implement the “view” interface so it can catch all of the interaction from the presenter.  Here’s a short example I coded yesterday to test a new summary screen:



    // Interface for the actual screen, implemented by an ASPX page


    public interface ISummaryView


    {


        bool GroupBySender { get; }


        bool GroupByReceiver { get; }


        bool GroupByStatus { get; }


        bool GroupByDays { get; }


 


        void SetRefreshTime();


        void Display(DataSet data, string[] fields);


    }


The DoFixture will implement the interface above and pass itself into a presenter class to catch the interaction.



    public class SummaryScreenFixture : DoFixture, ISummaryView


    {


        private bool _groupByDays;


        private bool _groupByStatus;


        private bool _groupByReceiver;


        private bool _groupBySender;


        private DataTable _table;


        private string[] _fields;


 


        public SummaryScreenFixture() : base()


        {


 


        }


 


        public void GroupBySenderIsChecked(bool active)


        {


            _groupBySender = active;


        }


 


        public bool GroupBySender


        {


            get { return _groupBySender; }


        }


 


        public void GroupByReceiverIsChecked(bool active)


        {


            _groupByReceiver = active;


        }


 


        public bool GroupByReceiver


        {


            get { return _groupByReceiver; }


        }


 


        public void GroupByStatusIsChecked(bool active)


        {


            _groupByStatus = active;


        }


 


        public bool GroupByStatus


        {


            get { return _groupByStatus; }


        }


 


        public void GroupByDaysIsChecked(bool active)


        {


            _groupByDays = active;


        }


 


        public bool GroupByDays


        {


            get { return _groupByDays; }


        }


 


        public void SetRefreshTime()


        {


            // no-op;


        }


 


        public void ClickRefresh()


        {


            SummaryPresenter presenter = new SummaryPresenter(this);


            presenter.CreateDisplay();


        }


 


        public void Display(DataSet data, string[] fields)


        {


            _table = data.Tables[0];


            _fields = fields;


        }


 


        public Fixture FieldsAre()


        {


            return new SummaryFieldFixture(_fields);


        }


 


        public Fixture DisplayIs()


        {


            return new SummaryDataFixture(_table);


        }


    }


In combination with other fixtures that setup the database state, I was able to quickly test the screen controller logic without ever starting up IIS. We’ve used this strategy in the past extensively with reporting screens to test sorting, filtering, and querying functionality. These tests will always be faster to setup and run than a test that executes through the full web screen.


Sorry about the very slow response Mike


– Jeremy

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.