In this post I'll talk about testing the user interface part of the Silverlight app. The other posts in this series are as follows (I'll update this list as they are published):
- Silverlight, MVVM & SharePoint - About this Series…
- Silverlight, MVVM & SharePoint - How I do MVVM
- Silverlight, MVVM & SharePoint - My favorite MVVM toolkit - MVVM Light Toolkit
- Silverlight, MVVM & SharePoint - Working with Commands
- Silverlight, MVVM & SharePoint - Working with Messages
- Silverlight, MVVM & SharePoint - Working with Dialogs
- Silverlight, MVVM & SharePoint - Testing the Business Logic
- Silverlight, MVVM & SharePoint - Testing the User Interface
- Silverlight, MVVM & SharePoint - Using Data Services
In the previous post in this series I discussed testing the business logic. But there's another important and critical piece to your application that you can test… the user interface! This is a major piece of the application, so why not test it!
Thankfully Visual Studio 2010 has a cool new capability called Coded UI Tests. Think of these as automating a user clicking stuff, but the framework can look at specific objects on the page and perform assertions against them.
You'll need Visual Studio 2010 Feature Pack 2 which, unfortunately, is only available for MSDN subscribers. It contains a Coded UI Test editor & support for Silverlight 4 tests aside from some other things. For more info I'd recommend checking out the MSDN library Testing the User Interface with Automated UI Tests section or this hands-on-lab on MSDN: Introduction to Coded UI Tests with Visual Studio 2010 Ultimate. This is also a great page discussing coded UI tests with Silverlight on MSDN: Testing Silverlight Applications with Coded UI Tests or Action Recordings.
There are a few things you need to in order to use coded UI tests in Silverlight.
- Your app must be a Silverlight 4 application.
- You need to add a reference to the Microsoft.VisualStudio.TestTools.UITest.Extension.SilverlightUIAutomationHelper.dll assembly in your Silverlight project.
- Each UI control you want to test has a unique identification property (see this for more info).
After you've done that, deploy your application so your Silverlight app is running correctly. Grab the URL of the page that launched it and copy it as you'll need it in a minute.
To create coded UI tests you need to create a regular old Test project in Visual Studio. You can't reuse a Silverlight Test project so you'll likely have to create a second one. In that project, add a new item to the project of type Coded UI Test. When prompted, pick the first option. You get this little widget called the UIMap - Coded UI Test Editor. Hit the Record button… this is going to record the steps it needs to undertake to get to your Silverlight application.
When the recording starts you want to launch an instance of the browser and navigate to the page where the app is, so I use the START » RUN option and type the following: iexplore.exe “[URL OF APP GOES HERE]".
Once the page loads, click the right-most button Generate Code in the UIMap - Coded UI Test Builder widget. It will prompt you for a name of the method which I will call NavigateToAndLaunchSilverlightApp & click the Add and Generate button. This will write out all the code necessary to implement the steps you just recorded.
Now we can add an assertion for something to test. In my app I want to see if categories were loaded and bound to a ListBox. To do this, click & hold the little target button in the UIMap - Coded UI Test Builder. Move the mouse over the first item in the ListBox very carefully and make sure the blue outline only shows you have selected a list item. Now, release the mouse button and let it analyze what it found. Make sure that the ControlType property is a ListItem. If not, try it again.
Let's add an assertion that we got a category back. It isn't going to look at the actual text being rendered as that's part of the template. Instead we want to see the specific object… so scroll down in the Control Specific grouping and find the DisplayText property. This should be the fully qualified name of the type you're binding to (in my case, ProductBrowser.Model.ProductCategory). I'll right click that property and pick Add Assertion. When prompted I want to enter what I want to check for (refer to this animated gif):
After adding the assertion, we have to generate the code for this test by clicking the Generate Code button again in the widget. I call mine Assert_ProductCategoryLoadedInListBox. Finally close the widget.
If you go back to the unit test in Visual Studio you'll see our two test methods we just generated:
Now run the test and see what happens! Make sure you close all instances of the browser and then run the test. Take your hands off the keyboard and you'll see the tests automate the launching of IE, navigating to your Silverlight application and it will check for a specific instance of the product item. Finally your test will pass. Cool stuff!
Obviously you can get quite a bit more complicated with these tests.