Using win forms with an MVC/MVP architecture, I would normally use a class to wrap a view to test the UI while using mocks for the model and controller/presenter. The wrapp
Because the Coded UI framework expires after Visual Studio version 2019 (Deprecated Coded UI), Microsoft recommends Appium with WinAppDriver for testing Windows applications (Desktop and UWP). You can use Appium (with WinAppDriver) or WinAppDriver directly to run the tests (WinAppDriver with or without Appium).
WinAppDriver directly
Here is a short description to work with the WinAppDriver directly:
download and install WinAppDriver:
WinAppDriver Release
enable Developer Mode in Windows settings
start the WinAppDriver:
C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe
create a new Visual Studio 2019 Unit Test Project (.NET Framework)
add the NuGet-Package: Appium.WebDriver Microsoft.WinAppDriver.Appium.WebDriver (comment from Microsoft: it is recommenced to use the WinAppDriver NuGet package to take full advantage of the advanced input with the Actions API.)
add a new class DesktopSession:
public class DesktopSession
{
protected const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
private const string NotepadAppId = @"C:\Windows\System32\notepad.exe";
protected static WindowsDriver<WindowsElement> session;
protected static WindowsElement editBox;
public static void Setup(TestContext context)
{
// Launch a new instance of Notepad application
if (session == null)
{
// Create a new session to launch Notepad application
var appCapabilities = new DesiredCapabilities();
appCapabilities.SetCapability("app", NotepadAppId);
appCapabilities.SetCapability("platformName", "Windows");
appCapabilities.SetCapability("deviceName ", "WindowsPC");
session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appCapabilities);
Assert.IsNotNull(session);
Assert.IsNotNull(session.SessionId);
// Set implicit timeout to 1.5 seconds to make element search to retry every 500 ms for at most three times
session.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1.5);
// Keep track of the edit box to be used throughout the session
editBox = session.FindElementByClassName("Edit");
Assert.IsNotNull(editBox);
}
}
public static void TearDown()
{
// Close the application and delete the session
if (session != null)
{
session.Close();
try
{
// Dismiss Save dialog if it is blocking the exit
session.FindElementByName("Nicht speichern").Click();
}
catch { }
session.Quit();
session = null;
}
}
[TestInitialize]
public void TestInitialize()
{
// Select all text and delete to clear the edit box
editBox.SendKeys(Keys.Control + "a" + Keys.Control);
editBox.SendKeys(Keys.Delete);
Assert.AreEqual(string.Empty, editBox.Text);
}
}
[TestClass]
public class UnitTest1 : DesktopSession
{
[TestMethod]
public void EditorEnterText()
{
Thread.Sleep(TimeSpan.FromSeconds(2));
editBox.SendKeys("abcdeABCDE 12345");
Assert.AreEqual(@"abcdeABCDE 12345", editBox.Text);
}
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
Setup(context);
}
[ClassCleanup]
public static void ClassCleanup()
{
TearDown();
}
}
(the sample code is mainly copied from WinAppDriver .NotepadTest).
Appium with WinAppDriver
If you want to run your tests using Appium, then you must have installed the correct version of the WinAppDriver on your machine. The installer of Appium should also install the WinAppDriver with the correct version on your machine (please install Appium for all users). In my case, unfortunately, this did not work. So I take a look in the file:
C:\Program Files\Appium\resources\app\node_modules\appium\node_modules\appium-windows-driver\lib\installer.js
Here you will find the correct version and the download path:
const WAD_VER = "1.1";
const WAD_DL = `https://github.com/Microsoft/WinAppDriver/releases/download/v${WAD_VER}/WindowsApplicationDriver.msi`;
If you have installed the correct WinAppDriver you can start Appium.
Important: you have to change the ApplicationDriverUrl
protected const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723/wd/hub";
Tools:
WindowsAppDriver and UI REcorder releases or Donwload the WinAppDriver repository and build the WinAppDriverUIRecorder.sln in the subdirectory tools\UIRecorder
Introducing WinAppDriver UI Recorder
Other links: WinAppDriver FAQ Appium
Try Ranorex V2.0 for WPF automation. With RanoreXPath and Ranorex repository test automation code could be completely seperated from identification information. Ranorex also provides a capture/replay editor based on RanoreXPath objects.
The question is still relevant, but many of the answers got obsolete. @deadpikle suggested a very good solution in the comment, I tried it and I want to make it as an answer in order to more people see it.
So, here is a library https://github.com/FlaUI/FlaUI. Here is a quick start guide for WPF app:
Install FlaUI.UIA3 from nuget
Write this to test if app runs correctly (but insert your string literals):
using FlaUI.Core;
using FlaUI.Core.AutomationElements;
using FlaUI.UIA3;
using FluentAssertions;
using System;
using Xunit;
namespace Functional
{
public sealed class General : IDisposable
{
private readonly Application _app = Application.Launch(@"..\App.exe");
[Fact]
public void AppStarts()
{
using var automation = new UIA3Automation();
Window window = _app.GetMainWindow(automation, TimeSpan.FromSeconds(3));
window.Should().NotBeNull("null means the window failed to load");
window.Title.Should().Be("App title",
"otherwise, it could be message box with error in case of the wrong configuration");
}
public void Dispose()
{
_app.Close();
_app.Dispose();
}
}
}
This code also works well in the GitHub Actions pipeline.
Manually. I'm not a big fan of automated UI testing if that is what you're getting at. I'm not sure about the WPF guidances (need to read thru aku's links).. because they are still solidifying so to speak... WPF has not stabilized from the point of 'what is the right way'. Unless you're using one of these evolving frameworks.. I'd be conservative w.r.t. effort
PS: you may want to watch this (Mary Poppendieck's Google Talk on Lean).. especially the part about what to automate in testing
Definitely look at TestAutomationFX.com. One can invest (OK, I did) a lot of time trying to capture / record events with White. (At the start of my quest I ignored the post or two in other places referring to it).
I of course second the other points about the best type of testing not being UI testing.
But if someone is going to do something automatable in the UI to get around shortcomings in other types of testing coverage, TAFX seems the quickest route there.
I would recommend TestAutomationFX as well for simple automation of ui testing. TestAutomationFX lets you work with netAdvantage tools for wpf aswell , which doesnt work with white and QTP. TestAutomationFX has a easy to use interface , it integrates with visual studio and has a good recorder for recording user events.