How to test a WPF user interface?

Solution 1:

As for the testing itself, you're probably best off using the UI Automation framework. Or if you want a more fluent and wpf/winforms/win32/swt-independent way of using the framework, you could download White from Codeplex (provided that you're in a position to use open source code in your environment).

For the gotchas; If you're trying to test your views, you will probably run in to some threading issues. For instance, if you're running NUnit the default testrunner will run in MTA (Multi-Threaded Appartment), while as WPF needs to run as STA (Single-threaded Appartment). Mike Two has a real easy getting-started on unit testing WPF, but without considering the threading issue. Josh Smith has some thoughts on the threading issue in this post, and he also points to this article by Chris Hedgate. Chris uses a modified version of Peter Provost's CrossThreadTestRunner to wrap the MTA/STA issues in a bit more friendly way.

Solution 2:

2016 Update: Use the free TestStack.White framework to automate WPF UI testing

  • Project White has been abandoned, but its successor TestStack.White is available via a NuGet package.
  • TestStack.White has utility methods for starting WPF apps, finding window/user control elements, clicking buttons/elements, simulating mouse and keyboard events, waiting, etc..
  • An example that will launch a WPF app, click a button, and check for result looks like the following:

    using TestStack.White;
    using TestStack.White.UIItems;
    using TestStack.White.Factory;
    
    [TestMethod]
    public void TestDoSomething()
    {
        //Opens the app
        var app = Application.Launch("MyApp.exe");
    
        //Finds the main window (this and above line should be in [TestInitialize])
        var window = app.GetWindow("My App Window Title", InitializeOption.NoCache);
    
        //Finds the button (see other Get...() methods for options)
        var btnMyButton = window.Get<Button>("btnMyButtonWPFname");
    
        //Simulate clicking
        btnMyButton.Click();
    
        //Gets the result text box 
        //Note: TextBox/Button is in TestStack.White.UIItems namespace
        var txtMyTextBox = window.Get<TextBox>("txtMyTextBox");
    
        //Check for the result
        Assert.IsTrue(txtMyTextBox.Text == "my expected result");
    
        //Close the main window and the app (preferably in [TestCleanup])
        app.Close();
    }