Как протестировать пользовательский интерфейс WPF?
Использование форм выигрыша с MVC/MVP, Я бы обычно использовал класс, чтобы обернуть представление для проверки пользовательского интерфейса при использовании mocks для модели и контроллера/презентатора. Класс обертки сделает большинство в пользовательском интерфейсе видимым свойством для тестового бегуна через свойства и события.
Будет ли это жизнеспособным подходом к тестированию WPF-приложения? Есть ли способ лучше? Есть ли какие-либо проблемы, требующие внимания?
Ответы
Ответ 1
Что касается самого тестирования, вам, вероятно, лучше всего использовать среду автоматизации пользовательского интерфейса. Или, если вы хотите более гибкий и независимый от wpf/winforms/win32/swt способ использования инфраструктуры, вы можете загрузить White из Codeplex (при условии, что вы в состоянии использовать открытый исходный код в своей среде).
Для гочей; Если вы пытаетесь проверить свои представления, вы, вероятно, столкнетесь с некоторыми проблемами многопоточности. Например, если вы работаете с NUnit, стандартный тестовый прогон будет работать в MTA (многопоточная квартира), тогда как WPF должен работать как STA (однопоточная квартира). Mike Two действительно легко приступил к модульному тестированию WPF, но без учета проблем с многопоточностью. У Джоша Смита есть некоторые соображения по поводу темы потоков в этом посте, и он также указывает на эту статью Криса Хедгейта. Крис использует модифицированную версию Peter Provost CrossThreadTestRunner для более дружественного решения проблем MTA/STA.
Ответ 2
@Matt David,
Прочитайте документацию и посмотрите образцы кода для Microsoft CompositeWPF (он же Prism). Это проект, созданный специально для обучения методам работы с архитектурой MVP/MVC в тестовом режиме. Их примерное приложение содержит модульные тесты для презентаторов\контроллеров и очень классные приемочные тесты для пользовательского интерфейса (они используют White framework для имитации действий пользователя)
Ответ 3
Вручную. Я не большой поклонник автоматизированного тестирования пользовательского интерфейса, если это то, что вы получаете. Я не уверен в руководстве WPF (нужно читать через ссылки aku).. потому что они все еще затвердевают, так сказать... WPF не стабилизировался с точки зрения "что это правильный путь". Если вы не используете одну из этих эволюционирующих фреймворков. Я был бы консервативным w.r.t. усилие
- Тестирование (автоматизированное, предпочтительно TDDed) логических/презентаторов/контроллеров безжалостно. Я не сторонник небрежности или летаргии.
- Держите пользовательский интерфейс тонким и получите несколько неприятных тестеров, чтобы пойти (ручная) трещина на нем с помощью разведочных испытаний - ничто не так хорошо, как "тестер из ада", когда дело доходит до пользовательских интерфейсов, Усилия: коэффициент усиления от автоматизации такого рода тестирования огромен, не поймает все и не имеет смысла... кроме как умиротворить более высокий "Look Mgr". Без рук! самоконтроля пользовательских интерфейсов!
PS: вы можете посмотреть это (Mary Poppendieck Google Talk on Lean).. особенно часть о том, что автоматизировать в тестировании
Ответ 4
Обновление 2016: используйте бесплатный каркас TestStack.White для автоматизации тестирования пользовательского интерфейса WPF.
- Project White был заброшен, но его преемник TestStack.White доступен через пакет NuGet.
- TestStack.White содержит служебные методы для запуска приложений WPF, поиска элементов управления окна /пользователя, нажатия кнопок/элементов, имитации событий мыши и клавиатуры, ожидания и т.д.
-
Пример, который запускает приложение WPF, нажимает кнопку и проверяет результат, выглядит следующим образом:
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();
}
Ответ 5
Prism (Composite WPF) построена в первую очередь с учетом "Testability". Пойдите для этого, если вы считаете, что это подходит вашему развитию.
Также здесь эпизод dotnetrocks, который вы могли бы прослушать, если вам нужна дополнительная информация о Prism в аудио.
Ответ 6
Для основ вы также можете посмотреть несколько коротких видеороликов на канале9 здесь и здесь.
Ответ 7
Вы также можете попробовать Guia. Это позволяет вам напрямую unit test одиночные WPF UserControls.
Ответ 8
Это будет работать просто отлично, проще, чем с выигрышными формами.
Проверьте "Руководство по качеству приложений WPF", он довольно много тестирует интерфейс WPF.
Также не забудьте класс AutomationPeer.
Ответ 9
Определенно посмотрите на TestAutomationFX.com. Можно инвестировать (хорошо, я сделал) много времени, пытаясь захватить/записать события с White. (В начале моего квеста я проигнорировал сообщение или два в других местах, ссылающихся на него).
Я, конечно, второй, другие точки, о лучшем типе тестирования, не являющемся тестированием пользовательского интерфейса.
Но если кто-то собирается сделать что-то автоматизированное в пользовательском интерфейсе, чтобы обойти недостатки в других типах тестирования, TAFX кажется самым быстрым маршрутом там.
Ответ 10
Попробуйте Ranorex V2.0 для автоматизации WPF. С кодом идентификации хранилища RanoreXPath и Ranorex можно полностью отделить от информации идентификации. Ranorex также предоставляет редактор захвата/воспроизведения, основанный на объектах RanoreXPath.
Ответ 11
Вместо использования автоматических тестеров вы можете создать настоящие модульные тесты для вашего графического интерфейса с IcuTest.
Ответ 12
Я бы рекомендовал TestAutomationFX также для простой автоматизации тестирования ui. TestAutomationFX позволяет работать с инструментами netAdvantage для wpf, а также работать с белым и QTP. TestAutomationFX имеет простой в использовании интерфейс, он интегрируется с визуальной студией и имеет хороший рекордер для записи пользовательских событий.
Ответ 13
Вы можете использовать автоматизацию пользовательского интерфейса: http://msdn.microsoft.com/en-us/library/ms747327.aspx
и http://www.telerik.com/automated-testing-tools/support/documentation/user-guide/write-tests-in-code/silverlight-test-automation/wpf-test-automation.aspx
Ответ 14
Поскольку срок действия инфраструктуры кодированного пользовательского интерфейса истекает после версии Visual Studio 2019 (устаревший кодированный пользовательский интерфейс), Microsoft рекомендует Appium с WinAppDriver для тестирования приложений Windows (для настольных ПК и UWP).
Вот краткое описание работы с WinAppDriver:
-
загрузите и установите WinAppDriver:
WinAppDriver Release
-
запустите WinAppDriver:
C:\Program Files (x86)\Драйвер приложения Windows\WinAppDriver.exe
-
создать новый проект модульного тестирования Visual Studio 2019 (.NET Framework)
-
добавить пакет NuGet: Appium.WebDriver
- добавить новый класс 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().ImplicitlyWait(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);
}
}
- Изменить код из класса UnitTest1
[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();
}
}
(пример кода в основном скопирован из WinAppDriver.NotepadTest).
Инструменты:
Другие ссылки:
WinAppDriver с или без Appium
Appium