07 - vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

23
Висновки з TDD погляд початківця Трішки лірики про процес Приклад реалізації тесту Віталій Зінченко [email protected]

Upload: igor-bronovskyy

Post on 05-Dec-2014

378 views

Category:

Education


3 download

DESCRIPTION

07 - Висновки з TDD, погляд початківця - Віталій Зінченко - IT Event 2013 (5) Буде розглянуто підхід розробки програмного забезпечення та тестів, який дозволить досягти наступних цілей: - глибокий та детальний аналіз вимог; - одне розуміння функціональності продукту для усіх членів команди; - хороша взаємодія між командами розробників та тестувальників; - високий рівень покриття продукту тестами; - скорочення часу необхідного для тестування; Результатом виконання перелічених пунктів стане налагоджений процес розробки продукту, порозуміння між учасниками команди і найголовніше - якісне ПЗ. Віталій Зінченко http://itevent.if.ua/lecture/visnovki-z-tdd-poglyad-pochatkivtsya

TRANSCRIPT

Page 1: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Висновки з TDD погляд початківця

Трішки лірики про процес

Приклад реалізації тесту

Віталій Зінченко

[email protected]

Page 2: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Чому виникло бажання про це розповісти?

Подяки:

• http://xpinjection.com

• Микола Аліменков

• Володимир Цукур

• Einar Ingebrigtsen

• Jasson Huggins

• Simon Steward

Page 3: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Робочий процес розробника

аналіз вимог

виділення неподільних елементів

визначення вхідних параметрів і результату

розробка функціоналу

перевірка

створення тестової версії

виправлення помилок

Page 4: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Робочий процес тестувальника

аналіз вимог

виділення неподільних елементів

визначення вхідних параметрів і результату

розробка тестових сценаріїв

перевірка тестової версії

звітування про помилки

Page 5: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Що тут не так?

Давайте вирішувати проблеми, ще до їх появи

ізольований аналіз вимог та їх уточнення

питання - як воно працює?

питання - як воно перевіряється?

Результат:

багато дрібних помилок

уточнення після реалізації

витрачений час

Page 6: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Єдина задача - єдина команда

Реалізація пліч-о-пліч:

аналіз і уточнення вимог

виділення функціональних частин

створення макету продукту

реалізація функціоналу

написання і розробка тестів

збереження робочих даних в одному місці

Page 7: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

І ми маємо отаке:

Page 8: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Перевірки при такому підході

менше запитань і узгоджень після реалізації

менше помилок-багів

розробник використовує тести в процесі написання

функціоналу

тестувальник займається створенням тестів, а не їх

проходженням

частіші та однакові регресивні перевірки

Page 9: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Як це все виглядає:

Unit Test, Visual Studio 2012 + NuGet

WebDriver + Selenium

Page 10: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Клас BaseObject

using OpenQA.Selenium; using Selenium; Using OpenQA.Selenium.Support.PageObjects; Using OpenQA.Selenium.Support.UI; namespace FaceBookTest { public class BaseObject { public static IWebDriver Driver; public static DefaultSelenium Selenium; public static void InitPage<T>(T pageClass) where T : BaseObject { PageFactory.InitElements(Driver, pageClass); } } }

Page 11: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Клас BaseTest

using Nunit.Framework; using OpenQA.Selenium.Firefox; using OpenQA.Selenium.IE; using OpenQA.Selenium.Chrome; using Selenium; namespace FaceBookTest { public class BaseTest : BaseObject { [TestFixtureSetUp] public void beforeClass(){ Driver = new FirefoxDriver(); //for IE Driver = new InternetExplorerDriver(@"<DOWNLOAD AND SPECIGY PATH //TO IEDERIVERSERVER HERE(//code.google.com/p/selenium)>"); Selenium = new WebDriverBackedSelenium(Driver, TestTools.homePage); Selenium.Start() } [SetUp] public void beforeTest(){ Driver.Navigate().GoToUrl(TestTools.homePage); } [TestFixtureTearDown] public void afterClass(){ Driver.Close(); Selenium.Close(); } } }

Page 12: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Клас TestTools

using NUnit.Framework; namespace FaceBookTest { class TestTools : BaseObject { public static string homePage = "http://www.facebook.com"; private const int DEFAULT_TIMEOUT = 60; public static void WaitingForElement(string locator, int timeOut = DEFAULT_TIMEOUT) { for (int i = 0; i < timeOut; i++){ if (Selenium.IsElementPresent(locator)){ return; } else{ System.Threading.Thread.Sleep(1000); } } Assert.Fail("Element with '" + locator + "' not found"); } } }

Page 13: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Елементи на Login-сторінці

public class LoginPage : BaseObject public const string USER_NAME_FIELD = "//input[@id='email']"; public const string PASSWORD_FIELD = "//input[@id='pass']"; public const string LOGIN_BUTTON = "//label[@id='loginbutton']/input"; public const string FAILED_LOGIN_TEXT = "//div/p[contains(text(),'The password you entered is incorrect')]"; [FindsBy(How = How.XPath,Using = USER_NAME_FIELD)] public IWebElement userNameField; [FindsBy(How = How.XPath, Using = PASSWORD_FIELD)] public IWebElement passwordField; [FindsBy(How = How.XPath, Using = LOGIN_BUTTON)] public IWebElement loginButton;

Page 14: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Події на Login-сторінці

public static LoginPage GetLoginPage() { LoginPage loginPage = new LoginPage(); InitPage(loginPage); return loginPage; } public LoginPage EnterUserName(string userName){ userNameField.SendKeys(userName); return GetLoginPage(); } public LoginPage EnterPassword(string password){ passwordField.SendKeys(password); return GetLoginPage(); } public UserHomePage ClickLoginButton() { loginButton.Click(); return UserHomePage.GetUserHomePage(); } public LoginPage IsLoginFailed(){ TestTools.WaitingForElement(FAILED_LOGIN_TEXT); return GetLoginPage();}

Page 15: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Тестові методи для Login-сторінки

namespace FaceBookTest { class LoginPageTools { private LoginPage loginPage = new LoginPage(); private UserHomePage userHomePage = new UserHomePage(); public LoginPageTools AssertUserName(string userName){ UserHomePage.AssertUserName(userName); return this; } } public LoginPageTools AssertLoginFailed(){ loginPage.IsLoginFailed(); return this;} public LoginPageTools PleaseLogin(string userName, string password){ BaseObject.InitPage(loginPage); loginPage. EnterUserName(userName). EnterPassword(password). ClickLoginButton(); return this; } } }

Page 16: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Елементи та події на HomePage

public const string DISPLAYED_USER_NAME = "//img[contains(@id,'profile_pic_header')]/../span[contains(text(),'#')]"; public const string USER_NAVIGATION_MENU = "//*[@id='userNavigationLabel']"; public const string LOGOUT_BUTTON = "//input[@value='Log Out']"; [FindsBy(How = How.XPath, Using = USER_NAVIGATION_MENU)] public IWebElement userNavigationMenu; [FindsBy(How = How.XPath, Using = LOGOUT_BUTTON)] public IWebElement logoutButton; public static UserHomePage GetUserHomePage(){ UserHomePage userHomePage = new UserHomePage(); InitPage(userHomePage); return userHomePage; } public UserHomePage AssertUserName(string testUserName){ TestTools.WaitingForElement(DISPLAYED_USER_NAME.Replace("#", testUserName)); return GetUserHomePage(); }

Page 17: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Тестові методи для HomePage

namespace FaceBookTest { class UserHomePageTools { private UserHomePage userHomePage = new UserHomePage(); public UserHomePageTools PleaseLogOut() { BaseObject.InitPage(userHomePage); userHomePage.userNavigationMenu.Click(); userHomePage.logoutButton.Click(); return this; } } }

Page 18: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Тест

namespace FaceBookTest { public class LoginPageTest : BaseTest { private static LoginPageTools loginPageTools = new LoginPageTools(); private static UserHomePageTools userHomePageTools = new UserHomePageTools(); [Test] public static void UserIsAbbleToLogin(){ loginPageTools. PleaseLogin(“[email protected]”, “fb!password13”). AssertUserName(“FBtest User”); UserHomePageTools.PleaseLogOut(); } [Test] public static void UserIsNotAbbleToLogin(){ PleaseLogin(“[email protected]”, “incorrectPassword”). AssertLoginFailed(); } } }

Page 19: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Результати

Page 20: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

SpecFlow Додати в проект:

SpecFlow

SpecFlow.NUnit

Створити SpecFlow Feature File

Page 21: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Код тесту

namespace FaceBookTest { [Binding] public class LoginFeatureSteps : BaseTest { private static LoginPageTools loginPageTools = new LoginPageTools(); private static UserHomePageTools userHomePageTools = new UserHomePageTools(); [AfterScenario()] public void TearDown() { afterClass(); } [Given(@"FaceBook Login Page is opened")] public void GivenFaceBookLoginPageIsOpened() { specFlowInit();} [When(@"Enter credentials (.*)/(.*) and press Login button")] public void WhenEnterCredentialsAndPressLogin(string p0, string p1) { loginPageTools.PleaseLogin(p0, p1); } [Then(@"User Name (.*) is displayed on the Home Page")] public void ThenUserNameIsDisplayedOnTheHomePage(string p0) { loginPageTools.AssertUserName(p0); userHomePageTools.PleaseLogOut(); } } }

Додати в BaseTest.сs public void specFlowInit() {beforeClass(); beforeTest();}

Page 22: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)

Результати

//

Page 23: 07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013 (5)