Тестирование UI
Джентельменский набор MVP NUnit NUnitForms RhinoMocks(NMock) Windows PowerShell
Тестирование UI Код, который легко тестировать Тесты, которые легко «кодить»
Model View Controller Model View Controller
Model View Controller Model Controller Display logic Presen- tation logic View
MVP Model View Presenter Event/Observer Model View Presenter
MVP public interface IOrderView { string Name {get;set;} int Amount {get;set;} void ShowMessage(string message); event VoidDelegate Cancel; event VoidDelegate Save; } public interface I Service { bool Send (string , string text); } Model View Presenter
MVP public class OrderPresenter { private I Service service; private IOrderView view; public OrderPresenter(I Service service, IOrderView view) { this.view = view; this.service = service; view.Save += view_Save; } void view_Save() { Order order = new Order(view.Name, view.Amount); if(order.Amount > 1000) "Order amount > 1000"); //Process order... } Model View Presenter
State-based тестирование Тестирование «чистых» функций Тестирование компонентов с малым числом зависимостей Тестирование компонентов обладающих «простыми состояниями»
State-based тестирование public class StateBasedUnitTest { public void DoTest() { Calculator calc = new Calculator(); int res = calc.Sum(10, 20); Assert.AreEqual(res, 30); }
К сожалению, Presenter… Не предоставляет «чистых функций» Будучи по своей природе «медиатором», зависит от большого числа компонентов Тестировать состояние Presenter-а абсолютно бесмысленое занятие
Пример тестового сценария Сотрудник вводит в форму «Создание заказа» название и стоимость заказа Пользователь нажимает кнопку «Сохранить заказ» Если стоимость заказа превышает 1000 рублей, то посылается главному менеджеру для проверки заказа Заказ сохраняется в системе Пользователю сообщается, что заказ успешно сохранился в системе
public void DoTest() { MockRepository mocks = new MockRepository(); //Создание mock-объектов I Service Service = mocks.CreateMock (); IOrderView view = mocks.CreateMock (); //Начало записи сценария view.Save += null; IEventRaiser raiser = LastCall.IgnoreArguments().GetEventRaiser(); using(mocks.Unordered()) { Expect.Call(view.Name).Return("Beer"); Expect.Call(view.Amount).Return("1001"); } Expect.Call( Service.Send ("", "")).IgnoreArguments(); Expect.Call(view.ShowMessage("")).IgnoreArguments(); //Проигрываем сценарий и проверяем соответствие записанному mocks.ReplayAll(); OrderPresenter presenter = new OrderPresenter( Service, view); raiser.Raise(); mocks.VerifyAll(); } Реализация interaction-based тестирования с RhinoMocks
NUnitForms public void Test() { Form1 form = new Form1(); form.Show(); TextBoxTester tbxName = new TextBoxTester("Name2"); TextBoxTester tbxAmount = new TextBoxTester("Amount2"); ButtonTester btnOK = new ButtonTester("btnOk"); FormTester appForm = new FormTester("Form1"); ExpectModal("Message", delegate { MessageBoxTester messageBox = new MessageBoxTester("Message"); messageBox.ClickOk(); }); tbxName.Enter("Beer"); tbxAmount.Enter("1001"); btnOK.Click(); form.Dispose(); }
Windows PowerShell Windows PowerShell™ — это новая командная оболочка Windows, разработанная в первую очередь для системных администраторов. Она включает интерактивную командную строку и среду исполнения сценариев.
Windows PowerShell Понятие командлета(сmdlet) в Windows PowerShell Создание своих командлетов на.Net Использование готовых библиотек Cmdlet-ов для автоматизации тестирования UI
Custom Cmdlets for UI Automation Cmdlet NameInput ParametersReturn Value / Effect get-windowwindowNameHandle to a top-level window get-controlhandleParent, ctrlNameHandle to a named control get-controlByIndexhandleParent, indexHandle to a non-named control send-charshandleControl, sSends string s to a control send-clickhandleControlClicks a control get-listBoxhandleControl, targetZero-based location of target get-textBoxhandleControlContents of TextBox as a string send-menumainIndex, subIndexFires application menu command.
Windows PowerShell # Test.ps1 write-host "Start test" $testPassed = $true invoke-item 'TestApp.exe' [System.Threading.Thread]::Sleep(2000) #get handlers $app = get-window "TestApp" $tbxName = get-control $app "Name" $tbxAmout = get-control $app "Amount" $btnOk = get-control $app "Ok" #init form send-chars $tbxName "Beer" send-chars $tbxAmout "1001" send-click $btnOk #... #get message box [System.Threading.Thread]::Sleep(2000) $mBox = get-window "Message" if( $mBox –eq $null ) { write-host “Test failed” } else { write-host "`Test passed" } write-host "End test" # end script
Windows PowerShell public class TestScript { public string CreatedBy{...} public string DateCreated{...} public int Priority{...} public string Tags{...} public int ExecutionTime{...} public int LastExecutionTime{...} } [Cmdlet(VerbsLifeCycle.Start, "TestScripts")] public class ExecuteScripts : Cmdlet {... private void executeScripts(TestScript[] scripts){...} } [Cmdlet(VerbsCommon.Get, "TestScripts")] public class GetScripts : Cmdlet {... private TestScript[] findScripts(string path){...} }
PS C:\> Get-TestScripts –Path.\MyTests | Where-Object -FilterScript {($_.Tags -contains "Order") -or ($_. Tags -contains "Customer")} | Execute-TestScripts PS C:\> Get-TestScripts –Path.\MyTests | Where-Object -FilterScript {($_. Tags -contains "Order")} | Sort-Object -Priority -Descending | Execute-TestScripts PS C:\> Get-TestScripts –Path.\MyTests | Where-Object -FilterScript {($_.Tags - contains "Order") –and ($_.CreatedBy -eq “Maxim") } | Sort-Object -CreatedTime -Descending | Execute-TestScripts Windows PowerShell
Коротков Максим, Finance Software Windows PowerShell