Category Archives: Unit Testing

Silverlight 2 has built in Unit Testing

Standard

image

As announced by Scott Guthrie in Mix08, and now on his blog, Silverlight 2 incorporates visual unit testing.  

One of the motivations for an MVC/MVP architecture for me is better unit testing of ui logic.  Sometimes it is very difficult to created automated visual tests for some platforms, such as Winforms. 

It appears (from the demo) that Silverlight allows pretty good testing of the actual user interface.    Probably more effective than testing ui logic with mock views.

Food for thought.  Perhaps this should affect the way we think about testing frameworks.

If you’re interested, take a look at this good (and short) video demo which gives you an overview of the whole thing:

Video walkthrough of the Silverlight 2 control unit tests – Jeff Wilcox

 

Links

Open Source automation frameworks for Winforms and other Win32 Apps

 

Share this post :

Advertisements

A reference "to that project" could not be added

Standard

As part of my research into doing test driven development on the Windows Mobile platform, I tried to create a “smart device” project level reference.

(See the post Unit Testing Smart Device Projects for more information about using Microsoft Test and unit testing on Windows Mobile)

As I haven’t found the information anywhere else, I thought I’d post my problem and the solution:

The Problem

When my test project was in Visual Basic, I got this brutal error message:

A reference to xxxxxxxxx could not be added:

image

A CSharp test project did manage to get to add the reference, but only after getting this message:

image

Does this mean I’ve finally found something CSharp can do better than VB.Net?  Surely not!

The Solution

After a great deal of messing around, I tried using the Microsoft Test Test Wizard to create the Visual Basic test project.  This worked.  The reason this worked was that it took a file reference instead.

So there’s your workaround.  Use a file reference.

Unit Testing Smart Device Projects

Standard

Screenshot of the Smart Client Software Factory's Gui Test Runner

A way of doing Test Driven Development on the Windows Mobile platform in the early days was not particularly easy.

For the development of Webby I created my own NUnit clone that worked inside the exe in debug mode.  This worked really well, but it was limited and I would have preferred something that was integrated into the IDE.

The developers of the “Mobile Client Software Factory” at Microsoft Patterns and Practices felt the need to create a unit testing environment that would enable full “test first” development.  Recently I had the need to investigate their solution, and have found very good.

The factory provides comprehensive unit tests for the application blocks that come with the factory, but more interestingly it provides a way for you to use the same testing framework.

This article below gives an outline of how tests are structured and how to do it.  

The structure of the tests

The test classes utilise the “Visual Studio Team Suite” attribute test markup ([TestClass], [TestMethod] etc).

These test classes are used by two test projects (assemblies):

  • A desktop test project for Visual Studio 2005 Team Suite
  • A mobile class library for running the unit tests on a mobile device

Both the desktop and mobile projects reside in the same project folder (with different names)

Creating the tests

The following procedures describe how you should create and run unit tests
To create and run unit tests on the desktop

  1. Create a Visual Studio 2005 Team System Edition test project that will run unit tests on the desktop.
  2. Add the <TestClass>, <TestMethod>, <TestInitialize>, and <TestCleanup> attributes described earlier to your classes to indicate which are test classes, test methods, initialization methods, and cleanup methods.  (TIP: Reference the application exe or dll as a “File Reference”)
  3. Run these unit tests using Visual Studio 2005 Team System or the TestDriven.NET test runner until all the tests pass.

Next, you can adapt these tests to run on the mobile device. The following procedure describes how you can use the GuiTestRunner utility to run your unit tests in the device emulator or on a mobile device.

To run unit tests in the emulator or on a device

  1. Add the following projects to your application project:
    • GuiTestRunner.csproj from the Tools\CFUnitTester\GuiTestRunner folder
    • TestRunner.csproj from the Tools\CFUnitTester\TestRunner folder
    • UnitTesting.csproj from the Tools\CFUnitTester\UnitTesting folder
  2. If you want to use the test utilities in your tests, also add the TestUtilities.csproj project from the Tools\TestUtilities folder. This project includes utilities to help you read application resources, access the application runtime folder, and provides stopwatches for measuring performance.
  3. Click Add on the File menu, and then click New Project. In the left-side tree view of the Add New Project dialog box, click Windows Mobile 5.0 Pocket PC. In the right-side window of this dialog box, click Class Library. Click OK to add the new project to your existing solution. Use the naming convention for test projects “[Module to be tested].Tests.CF“.
  4. Close Visual Studio and, in Windows Explorer, move your new Class Library project into same folder as desktop test project. This allows the device test project to share the same files as the desktop test project more easily.
  5. Re-open Visual Studio, and open your application solution. In Solution Explorer, right-click the References entry for your application project, and then click AddReference. On the Projects tab of the AddReference dialog box, select your test project, and click OK.
  6. With the device test project selected in Solution Explorer, click Show AllFiles on the Project menu. This reveals all files and folders in the same folder as the desktop test project.
  7. Select all the test and supporting files in Solution Explorer, right-click, and then click Include in Project.
  8. Add the compiler directive to select the appropriate test class namespace at compile time.

    #if PocketPC
     Imports Microsoft.Practices.Mobile.TestTools.UnitTesting
    #else
     Imports Microsoft.VisualStudio.TestTools.UnitTesting
    #endif

  9. In Solution Explorer, right-click your test project, and then click Properties. On the Properties page, click the Devices tab. Change the value for the Output file folder in the Deployment Options section to %CSIDL_PROGRAM_FILES%\GuiTestRunner to ensure that your tests deploy to the same folder as the as the GuiTestRunner utility.
  10. Deploy and execute the GuiTestRunner utility

Links

Rhino Mocks Constraints In VB.Net

Standard

Over the past few months I’ve been getting into the Rhino Mocks mocking framework. 

A timesaver for me has been the call “LastCall.IgnoreArguments”.  This has been handy because many of the parameters in my calls are objects that I can’t really verify.

For Example:

loTransLog.RecordUpdate(Nothing,Nothing)
LastCall.IgnoreArguments()

Although this is good in that I can keep working, I have found this a little annoying as sometimes a couple of the arguments to my function are verifiable, yet I’m calling “IgnoreArguments”.  In the case above, the first parameter is a string which is checkable.

Ayende has come to the rescue for people who use IgnoreArguments with the concept of “Constraints”.    Constraints allow you to verify arguments individually.

In the example cited, I can verify the first parameter like this:

loTransLog.RecordUpdate(Nothing,Nothing)
LastCall.IgnoreArguments().Constraints(Constraints.Is.Equal("foo"), Constraints.Is.Anything)

There are lots of checks you can do besides equality.   I can even improve the above example by ensuring the second parameter (an object) is of an expected type: 

loTransLog.RecordUpdate(Nothing,Nothing)
LastCall.IgnoreArguments().Constraints(Constraints.Is.Equal("foo"), Constraints.Is.TypeOf(GetType(TheTypeIWantThisToBe)))

Read about all the other constraints available here:

Rhino Mocks Constraints – Ayende @ Wiki

The Mystery of the Disappearing Tests in Microsoft Test

Standard

image

I have finally solved the mystery.   A couple of days ago I wrote a four tests in a test class.  All seemed well.  Here there are:

image

Then “it” happened.  All of a sudden, one or more of the tests in the “Test View” would vanish without explanation.  I would rename one of them and it would return, only to vanish later.

I renamed the test methods, googled the problem, deleted code, duplicated code, when generally crazy without any luck. 

Do you believe that the position of certain declarations in your class makes any difference?  I didn’t believe so.  Until now.  In the past I liberally scattered private declarations and member variables throughout my class where I felt necessary, unshackled by the VB6esque standard of declaring everything at the top.    As it turns out, the old standard wouldn’t have saved me either…

The Problem

It turns out the “poison” which prevents Microsoft Test from finding tests is a delegate declaration.  Declare any delegate in your code and all test methods declared after that delegate will be invisible to test view.

Here’s a VB.Net example:

Private Delegate Sub ThisStopsTheFollowingBeingDetected()
    <TestMethod()> Public Sub TheInvisibleTestMethod()

    End Sub

The Solution

The only way of solving the problem is to move your delegate declarations to  the bottom of your class file:

    <TestMethod()> Public Sub TheInvisibleTestMethod()

    End Sub

    Private Delegate Sub ThisIsDelcaredAtTheBottom()

End Class

 Strange but true. 

This problem with detected in Visual Studio 2005 Team Edition for Developers.

The issue is tracked at https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=288973

Presenter First Pattern

Standard

There’s a really interesting podcast series running over on Microsoft’s Channel 9 ARCast.net that involves not only a discussion of the “Presenter First” pattern, but a discussion of Model View Presenter in general.  I’ve found it a great introduction to the subject.

It’s in 3 parts, starting with:

http://channel9.msdn.com/ShowPost.aspx?PostID=312315

 

Raising events (from a mock) using Rhino Mocks in VB.Net

Standard

 I’ve been doing some investigation of Passive View (MVP) architecture for Smart Client applications.

 The article Raising events (from a mock) using Rhino Mocks By Jean-Paul S. Boodhoo outlines the issues and gives some solutions to mocking “View” classes in MVP from a C# point of view.  In this post I’ll show some equivalent VB.Net code samples.

About Passive View 

The Passive View involves three components:

  • Model – Responsible for reading, saving  and validating the business data
  • View – Responsible for displaying data and accepting input from the user
  • Presenter – It provides the “glue” between the View and Presenter.  It copies data from the Model to the View and relays commands from the View to the Model.

(This differs from MVC in that there is no direct communication between Model and View)

The model and the view implement interfaces which are used by the Presenter to communicate with them.

By utilising interfaces, these interfaces can be “Mocked” using a mocking framework such as Rhino Mock.

About Mocking

The purpose of mocking is to ease testing by allowing the developer to create mock implementations of custom objects and verify the interactions using unit testing.

In MVP, the view is usually implemented by a difficult-to-test (or slow-to-test) user interface form.  Using a Mocking framework allows you to create a substitute for the user interface that runs quickly and accurately simulates the user interface from the Presenter’s viewpoint.

Find out more about Rhino Mocks at it’s project page.

Raising Events

An important aspect of the View interface is that it defines events that are raised in order to communicate input actions to the Presenter.

This is not completely straight forward.

Here’s an example of one of a View interface:

Public Interface IPersonalView
    Property Name() As String
    Property Address() As String
    Property Age() As Integer
    Event OnRead()
    Event OnSave()
End Interface

Here’s an example of a presenter that consumes views that implement the IPersonalView interface:

Public Class PersonalPresenter

    Protected WithEvents View As IPersonalView
    Protected Model As IPersonalModel
    Public Sub New(ByVal view As IPersonalView, ByVal model As IPersonalModel)
        Me.View = view
        Me.Model = model
    End Sub

    Public Sub DisplayCustomerDetails() Handles View.OnRead

        ' Ask Model to populate itself
        Model.DoRead()

        ' Transfer information
        With Me.View
            .Name = Model.Name
            .Address = Model.Address
            .Age = Model.Age
        End With

    End Sub
    Public Sub DoUpdate() Handles View.OnSave
        With Me.Model
            .Name = View.Name
            .Address = View.Address
            .Age = View.Age
        End With

        Model.DoSave()
    End Sub

End Class

You’ll notice that the first thing the presenter does (using the WithEvents keyword) is subscribe to events. 

In order to correctly “mock” a view then, we have to program the mock to expect this subscription.  Here is a Test:

<TestClass()> _
Public Class PersonalPresenterTest

    Private moMockery As MockRepository
    <TestInitialize()> _
    Public Sub MyTestInitialize()
        moMockery = New MockRepository

    End Sub

    <TestCleanup()> _
    Public Sub MyTestCleanup()

        moMockery.VerifyAll()

    End Sub
    <TestMethod()> _
    Public Sub Construction_ShouldSubscribeToEventsOnView()
        ' Mock the View
        Dim loView As IPersonalView = moMockery.CreateMock(Of IPersonalView)() 

        AddHandler loView.OnRead, Nothing
        LastCall.Constraints(Constraints.Is.NotNull())

        AddHandler loView.OnSave, Nothing
        LastCall.Constraints(Constraints.Is.NotNull())

        moMockery.ReplayAll()
        Dim target As PersonalPresenter = New PersonalPresenter(loView, Nothing)

    End Sub

End Class

 The important lines here are:

AddHandler loView.OnRead, Nothing
LastCall.Constraints(Constraints.Is.NotNull())
 The first line simulates what the WithEvents call does, which is to call AddHandler on all the handled events.

Raising An Event

Listening for the wireup isn’t enough however.    To properly simulate true view actions, we need to raise events to the Presenter (such as OnRead).  Rhino Mock provides a special object called an “EventRaiser”.

Call LastCall.GetEventRaiser after the AddHandler to get this object, then call the Raise method to raise the event:

' Mock the View
Dim loView As IPersonalView = moMockery.CreateMock(Of IPersonalView)() 

AddHandler loView.OnRead, Nothing
LastCall.Constraints(Constraints.Is.NotNull())

Dim loOnReadEventRaiser As Rhino.Mocks.Interfaces.IEventRaiser = LastCall.GetEventRaiser

AddHandler loView.OnSave, Nothing
LastCall.Constraints(Constraints.Is.NotNull())

moMockery.ReplayAll()

Dim target As PersonalPresenter = New PersonalPresenter(loView, loModel)

' Raise the read event on the "view"
loOnReadEventRaiser.Raise()

This gives me the fundamental building blocks for mocking views.