.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]

Comments

José Romaniello wrote re: NHProf and Caliburn Testability
on 10-30-2009 4:23 PM

Excellent post Rob. I really love Caliburn.Testability.

Actually my test has a lot of magic strings, because in Chinook Media Manager I have not used the concept of ViewStrategy. For those who are using View Strategy (I think this is the name caliburn uses) , you can take my test and remove a chunk of logic! so this test will be very simple. I will write a sample soon.

On the other hand, I see three level of test here and each level test different things.

*My code do exactly what you wrote in BindingsDoNotHaveErrors. This is the first level; I used to think in this way "Each bound property in the View should exist in the ViewModel".

*The second level, is what you wrote in "NameIsBound" and "StatisticsAreBound". My test does not ensure this. Those tests means "This property of the ViewModel should be bound  in the UI" or "This VM property should be -displayed- in the View" (but you can bind something like Width so "displayed" is a poor).

*The third level, is more complex... Its define the following:

"The property "width" of the TextBlock named "FullName" should be bound to the property "FullNameWidth" of the ViewModel".

DotNetShoutout wrote NHProf and Caliburn Testability - Rob Eisenberg - Devlicio.us
on 11-01-2009 1:28 AM

Thank you for submitting this cool story - Trackback from DotNetShoutout

NHibernate blog wrote NHibernate and WPF: Test Databinding with Caliburn
on 11-15-2009 12:10 PM

As I said before, for the Chinook Media Manager I’m not using neither Caliburn nor Prism . But, whenever

uberVU - social comments wrote Social comments and analytics for this post
on 11-24-2009 2:17 AM

This post was mentioned on Twitter by EisenbergEffect: Just blogged #NHProf and #Caliburn testability http://bit.ly/1IACSP

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)