.NET & Funky Fresh

Syndication

News

  • <script type="text/javascript" src="http://ws.amazon.com/widgets/q?ServiceVersion=20070822&amp;MarketPlace=US&amp;ID=V20070822/US/bluspiconinc-20/8001/8b68bf4b-6724-40e7-99a5-a6decf6d8648"> </script>
NHProf and Caliburn Testability

I’ve heard some developers asking about UI testing lately.  Specifically, there have been some questions about what we did with NHProf.  So, I thought I would write a little bit about that here. 

There are a variety of different types of tests you can do.  In my experience some have a better ROI than others.  For example, we don’t do any UI testing with automation APIs.  Those are pretty painful, brittle tests to write and we haven’t worked in scenarios where they would really help us.  The two main types of UI testing we tend to do are Unit Tests of the View Model and Binding Validation Tests against the Views.

View Model Tests

There are many advantages in taking a View Model approach to building your UI.  When we build VMs we try and push as much of the UI state into our models as possible.  By doing this we “virtualize” our entire UI, allowing us to simulate a large percentage of the UI behavior without ever opening a Window or showing anything on screen.  This is great for testability.  It means, we can use simple state based unit tests to verify the behavior of our UI.  Here’s a simple example from NHProf:

public class StatementFilterTestFixture
{
    private readonly FilterServiceModel service;
    private readonly IList<IStatementSnapshot> statements;

    public StatementFilterTestFixture()
    {
        statements = new List<IStatementSnapshot>
                         {
                             create_a_statement(100, "hello"),
                             create_a_statement(200, "select * from something"),
                             create_a_statement(300, "select field1 from something"),
                             create_a_statement(400, "select monkey,ninja,pirate,robot from floating_island"),
                             create_a_statement(500, ""),
                         };

        service = new FilterServiceModel();
    }

    [Fact]
    public void Can_filter_by_both_duration_for_values_less_than_300_and_contains_text()
    {
        var filters = new ObservableCollection<IFilter>
                          {
                              new FilterByDuration
                              {
                                  Operator = ExpressionType.LessThan, 
                                Value = "300"
                              },
                              new FilterBySqlContains {Text = "something"}
                          };

        service.Filters = filters;

        Assert.Equal(1, statements.Where(x => service.FilterStatement(x)).Count());
    }
}

Binding Validation Tests

While the WPF/SL data binding mechanism opens the door to building rich View Models, it also introduces a new problem: potential binding expression errors.  Because we didn’t want to give up the productivity benefits of databinding and View Models, we chose to take some time to build a binding validation framework.  We then write simple tests to insure that there are no typos or silly mistakes in our binding expressions.  Here’s an example test from NHProf:

public class StatisticsDetailsTestFixture : ViewTestFixtureBase
{
    private readonly ValidationResult<StatisticsModel> bindings;

    public StatisticsDetailsTestFixture()
    {
        bindings = Validator.For<StatisticDetailsView, StatisticsModel>()
            .Validate();
    }

    [Fact]
    public void BindingsDoNotHaveErrors()
    {
        Assert.False(bindings.HasErrors, bindings.ErrorSummary);
    }

    [Fact]
    public void NameIsBound()
    {
        Assert.True(bindings.WasBoundTo(x => x.DisplayName));
    }

    [Fact]
    public void StatisticsAreBound()
    {
        Assert.True(bindings.WasBoundTo(x => x.SortedStatistics));
    }
}

You can actually take this one step farther as José Romaniello has in testing his Chinook Media Manager.  Take a look at this sweet piece of code.


Posted 10-30-2009 3:07 PM by Rob Eisenberg

[Advertisement]

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)