ITEvent Висновки з TDD, погляд початківця
description
Transcript of ITEvent Висновки з TDD, погляд початківця
Висновки з TDDпогляд початківця
Трішки лірики про процес
Приклад реалізації тесту
Віталій Зінченко
Чому виникло бажання про це розповісти?
Подяки:
• http://xpinjection.com
• Микола Аліменков
• Володимир Цукур
• Einar Ingebrigtsen
• Jasson Huggins
• Simon Steward
Робочий процесрозробника
аналіз вимог виділення неподільних елементів визначення вхідних параметрів і результату розробка функціоналу перевірка створення тестової версії виправлення помилок
Робочий процес тестувальника
аналіз вимог виділення неподільних елементів визначення вхідних параметрів і результату розробка тестових сценаріїв перевірка тестової версії звітування про помилки
Що тут не так?
Давайте вирішувати проблеми, ще до їх появи
ізольований аналіз вимог та їх уточнення питання - як воно працює? питання - як воно перевіряється?
Результат: багато дрібних помилок уточнення після реалізації витрачений час
Єдина задача - єдина команда
Реалізація пліч-о-пліч: аналіз і уточнення вимог виділення функціональних частин створення макету продукту реалізація функціоналу написання і розробка тестів збереження робочих даних в одному місці
І ми маємо отаке:
Перевірки при такому підході менше запитань і узгоджень після реалізації менше помилок-багів розробник використовує тести в процесі написання
функціоналу тестувальник займається створенням тестів, а не їх
проходженням частіші та однакові регресивні перевірки
Як це все виглядає:Unit Test, Visual Studio 2012 + NuGet
WebDriver + Selenium
Клас 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);
}}
}
Клас BaseTestusing 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();
} } }
Клас TestToolsusing 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");} } }
Елементи на Login-сторінці
public class LoginPage : BaseObjectpublic 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;
Події на 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();}
Тестові методи для 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;} } }
Елементи та події на HomePagepublic 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();}
Тестові методи для HomePage
namespace FaceBookTest{
class UserHomePageTools{
private UserHomePage userHomePage = new UserHomePage();
public UserHomePageTools PleaseLogOut(){
BaseObject.InitPage(userHomePage);userHomePage.userNavigationMenu.Click();userHomePage.logoutButton.Click();return this;
}}
}
Тест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();
} }}
Результати
SpecFlowДодати в проект:
SpecFlow
SpecFlow.NUnit
Створити SpecFlow Feature File
Код тесту
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.сspublic void specFlowInit(){beforeClass(); beforeTest();}
Результати
//