Silverlight Testing with Microsoft Silverlight Testing Framework

Summary

This page intents to explain in simple non-technical words how some of the unit testing, specifically testing for the designer portion of the project, is being done. This page contains examples of some unit tests and an explanation of their behavior.

1. Getting Familiar with Silverlight

If you are familiar with Silverlight already feel free to move on to section 2 of this page

For those of you that are not familiar with the Silverlight way of things, allow me to mention a couple of concepts to get you on the right track and to ease your understanding of the unit tests to follow.

Silverlight, in a nutshell, it’s driven by UserControls. These are Xaml files with code behind just like many other technologies from Microsoft, in Silverlight they are “rendered” when they are called in your browser.

For example:

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

This Xaml, which represents a UserControl, will display a TextBlock with the Text content of Hello World.

These UserControls as you would expect, can be constructed in your code behind to dynamically add more content to it. For example:

TextBlock textBlock = new TextBlock();
textBlock.Text = "Hello World";
LayoutRoot.Children.Add(textBlock);

To finalize this short Silverlight review, let me just say that obviously you can add as many other classes to a Silverlight project allowing the use of all of the wonders of Object Oriented programming, however only the UserControls will be the ones seen in the browser.

That’s it!

2. Lets jump right to it…

A simple file to test, and for the purpose of this example, it’s Editor.xaml file. This file is divided in 4 sections, when you open the Editor in a browser you would see the following:

editor screenshot

As you can see there are 4 sections ( Menu, Tool Bar, Designer, Status Bar ). In Silverlight terms these sections are called Borders (I said I wouldn’t get technical, I know). The simplest test that I can think of, is to test if the rendered Editor Xaml page has 4 sections. Here is what the test would look like:

[TestMethod]
[Asynchronous]
public void XAML_EditorContainsFourRowsTest()
{
//Preconditions
int rowDefinitions = 4;

//Actions
TestPanel.Children.Add(_page);

//Postconditions
EnqueueCallback( (Action)(() => Assert.AreEqual(_page.LayoutRoot.RowDefinitions.Count, rowDefinitions )));
EnqueueTestComplete();
}

The first thing you’ll notice is that this test looks similar to what a test would look in any other framework, i.e. MbUnit, etc.. The next thing you’ll notice is the [Asynchronous] tag. This is because Silverlight Unit Test Framework has support of asynchronous calls that are used when UserControls have data driven service calls. The last thing you’ll notice is that I’ve divided the method in 3 sections. I do it because it looks organized and I think is good practice. Preconditions includes initialization of variables and objects later used in the postconditions assertions against data gathered in the actions section. Actions includes calls to the object in test, in the example “_page” was added to the TestPanel UserControl. Postconditions includes assertions. Calls to EnqueueCallback and EnqueueTestComplete are part of the Asynchronous feature.

If this test wasn’t Asynchronous it would look like this:

[TestMethod]

public void XAML_EditorContainsFourRowsTest()

{

//Preconditions

int rowDefinitions = 4;

//Actions

TestPanel.Children.Add(_page);

//Postconditions

Assert.AreEqual(_page.LayoutRoot.RowDefinitions.Count, rowDefinitions );

}

Now, lets look at a more involved test. This next test is a test to a method in the AccordionToolBox UserControl.

The Accordion ToolBox currently looks like this:

accordion toolbox screenshot

Simply has an Accordion Silverlight control with some AccordionItem Silverlight controls and inside of each AccordionItem there is a StackPanel Silverlight control with some Buttons in it. In the UltiStudio world this are the equivalents:

  • AccordionItem EQUALS Section
  • Button inside StackPanel of AccordionItem EQUALS a Section Item

Here is a test to make sure that the code creating a section actually creates a section behind the scenes or dynamically.

[TestMethod]

public void InitializeSectionContent_Test()

{

//Preconditions

ToolBoxSection toolBoxSection = new ToolBoxSection("General", 1);

ToolBoxItem item = new ToolBoxItem("1 Column Section", 1, 1);

toolBoxSection.Items = new Collection();

toolBoxSection.Items.Add(item);

int expectedSectionSize = 1;

//Actions

AccordionItem accordionItem = _accordionToolBox.InitializeSectionContent(toolBoxSection);

StackPanel accordionContent = accordionItem.Content as StackPanel;

//Postconditions

Assert.IsNotNull(accordionItem);

Assert.AreEqual(accordionContent.Children.Count, expectedSectionSize);

}

Assuming you read the previous test, you’ll know how this test is divided. The test is simple hardcoding a section with an item and passing it to the InitializeSectionContent method in the AccordionToolBox UserControl, then the test verifies that the method created an AccordionItem with the section properties which include the item inside its StackPanel.

As per the comment I received from Robert, the _accordionToolBox object is variable that I initialized in the setup portion of the fixture. It would look something like this:

[TestClass]

public class AccordionToolBoxTests : SilverlightTest

{

private AccordionToolBox _accordionToolBox;

private Mock _mockFactory;

List _sections;

[TestInitialize]

public void SetUp()

{

_mockFactory = new Mock(MockBehavior.Strict);

_sections = new List();

_accordionToolBox = new AccordionToolBox(_mockFactory.Object);

TestPanel.Children.Add(_accordionToolBox);

}

Don’t mind the Mock if you are not familiar with it, Mock falls outside the scope of this article.

For now, I will leave this document as is, and if you have questions and suggestion please let me know, I will keep adding to it along with our development.