Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Automated UI Testing with Guia

0.00/5 (No votes)
1 Jul 2010 1  
Unit-Testing of WPF User Controls via UI automation

Introduction

Guia is an open-source library for .NET which supports the automation of WPF applications. The Library allows access to, and remote control of, miscellaneous WPF-components in an easy and comfortable way. So it can easily be used for automated UI testing. A distinctive feature is the possibility to directly run and test WPF windows and UserControls, without the need for a previously created executable application (EXE file). This enables the writing of test cases for the GUI during development and thus to pursue a test driven approach in a consequent manner.

The Guia (Graphical User Interface Automation) library is avaiable at http://guia.codeplex.com.

Using the Code

Imagine you have a complex WPF UserControl. The correctness of the UserControl shall be proved by automatic UI-tests. Maybe you do also use the MVVM pattern. In that case, you might also want to test the data bindings from the view (UserControl) to the view model and vice versa. Since you follow the test driven approach, these things should be tested stand-alone.

Write a Test with Simulated User Operations

In the following example, we are going to write a test-case for a simple WPF UserControl. The UserControl enables to add new persons to a table. The name of the UserControl is "PersonUserControl". The XAML code is not posted here, but it can be downloaded.

The UserControl looks like this:

guia_1.gif

In the test-case, we would like to simulate a user who does the following:

  1. Enter the name
  2. Enter the firstname
  3. Select a country
  4. Invoke the button "Add"

After this procedure, the test-case should verify whether the person has being added properly.

  1. Check if there is a new entry in the data-grid
  2. Check if the cells of the new entry contain the data expected

Now, we setup a unit-test with MSTest. First, we have to start our UserControl. Since this has to be done prior to every test-case execution, we write an initialize method for that purpose:

CustomControl control = null;

[TestInitialize()]
public void MyTestInitialize()
{
    this.control = CustomControl.Start<PersonUserControl>();
}

As we have started the User-Control, we also need to stop it once. We do that in our cleanup method:

[TestCleanup()]
public void MyTestCleanup()
{
    control.Stop();
}

Now, we can start with our test-case which simulates a user adding a new person.

[TestMethod]
public void TestAddPerson()
{
    control.Get<TextBox>("txtFirstname").Value = "Roger";
    control.Get<TextBox>("txtName").Value = "Smith";
    control.Get<ComboBox>("cmbNationality").GetItem("Switzerland").Select();
    control.Get<Button>("btnAdd").Invoke();
    DataGrid_WpfToolkit dataGrid = control.Get<DataGrid_WpfToolkit>("dataGrid");

    Assert.AreEqual("Smith", dataGrid[0, 0].TextValue);
    Assert.AreEqual("Roger", dataGrid[0, 1].TextValue);
    Assert.AreEqual("Switzerland", dataGrid[0, 2].TextValue);
}

When we execute the test-case now, we will notice that a window is opened in the background and the defined data is entered and the actions executed.

Write a Test to Check the Data Binding

We use the MVVM pattern so that we have a view-model for every view (UserControl). Now, we would like to test the proper binding of the view-model to the view. First of all, we need a view model for our UserControl. This view model (PersonUserControlViewModel) is pretty straight-forward and is not posted here. It is avaiable in the sample-project though. Now we want to set the view model as the UserControl's DataContext. For that purpose, we use an action when initializing the UserControl in the test-case:

CustomControl control = null;
PersonUserControlViewModel viewModel = null;

[TestInitialize()]
public void MyTestInitialize()
{
    this.viewModel = new PersonUserControlViewModel();
    this.control = CustomControl.Start((c) => c.DataContext = viewModel);
}

First we want to verify whether data entered from a user in the GUI is also avaiable in the view model:

[TestMethod]
public void TestDataBindingGUI2VM()
{
    control.Get("txtFirstname").Value = "Roger";
    control.Get("txtName").Value = "Smith";
    control.Get("cmbNationality").GetItem("Switzerland").Select();

    Assert.AreEqual("Roger", viewModel.Firstname);
    Assert.AreEqual("Smith", viewModel.Name);
    Assert.AreEqual("Switzerland", viewModel.Nationality);
}

As you will see, this test succeded.

Now we would like to verify the reverse. If the view model is changed, the GUI should also update immediately.

[TestMethod]
public void TestDataBindingVM2GUI()
{
    viewModel.Firstname = "Roger";
    viewModel.Name = "Smith";
    viewModel.Nationality = "Switzerland";

    Assert.AreEqual("Roger", control.Get("txtFirstname").Value);
    Assert.AreEqual("Smith", control.Get("txtName").Value);
    Assert.AreEqual("Switzerland", 
	control.Get("cmbNationality").SelectedItem.TextValue);
}

Write a Test for an Entire Application

Until now, we only tested WPF UserControls. Guia also provides the possibility to automate and test entire applications. This feature can be used to write automated acceptance-tests for example.

The following code starts and tests an entire application. The sample application shows a window named "Sample Main Window" which contains the previously introduced UserControl.

[TestMethod]
public void TestEntireApp()
{
    // Init
    Application app = Application.Start(@"C:/Sample.exe");
    Window window = app.GetWindowByName("Sample Main Window");

    // Simulate user interactions
    window.Get<TextBox>("txtFirstname").Value = "Roger";
    window.Get<TextBox>("txtName").Value = "Smith";
    window.Get<ComboBox>("cmbNationality").GetItem("Switzerland").Select();
    window.Get<Button>("btnAdd").Invoke();
    DataGrid_WpfToolkit dataGrid = window.Get<DataGrid_WpfToolkit>("dataGrid");

    // Assertions
    Assert.AreEqual("Smith", dataGrid[0, 0].TextValue);
    Assert.AreEqual("Roger", dataGrid[0, 1].TextValue);
    Assert.AreEqual("Switzerland", dataGrid[0, 2].TextValue);
}

Further examples and code-snippets can be found in the official documentation.

History

  • 1st July, 2010: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here