понедельник, 30 мая 2011 г. - www.msmirnov.ru

Создание тестов для Selenium на C# для web-приложений на ASP.NET


Как я и обещал ранее здесь, привожу пример разработки тестовых сценариев для автоматизированного тестирования web-приложений на C# с использованием библиотеки Selenium 2.0b3.

Для первой версии Selenium разработка скриптов на C# также возможна, но она довольно сильно отличается и обладает гораздо меньшими возможностями, так что я бы не рекомендовал ее использовать. При этом, такой продукт, как Selenium IDE, позволяет осуществлять генерацию C# кода только для первой версии Selenium, поэтому для нас он также получается не актуален.

Далее по шагам рассмотрим пример создания тестового сценария проверки логина на тестируемый сайт.
  1. В Visual Studio.NET cоздаем новый проект – библиотеку классов на C#.
    В данную библиотеку помещаем ссылки на библиотеки Selenium:
    • Selenium.WebDriverBackedSelenium
    • WebDriver.Common
    • WebDriver.Remote
    • WebDriver.Remote.Common
    • WebDriver.Firefox
    • WebDriver.IE

    Все эти библиотеки доступны для загрузки с сайта http://seleniumhq.org/download – Скачать необходимо Selenium WebDriver версии 2.0b3 – речь в статье пойдет о ней.

  2. Создаем класс TestFramework который будет предоставлять нам основные функции по выполнению скриптов.

       1:  public class TestFramework
       2:      {
       3:          static RemoteWebDriver _WebDriver;
       4:   
       5:          public static RemoteWebDriver WebDriver
       6:          {
       7:              get
       8:              {
       9:                  if (_WebDriver == null)
      10:                      _WebDriver = new FirefoxDriver();
      11:   
      12:                  return _WebDriver;
      13:              }
      14:          }
      15:   
      16:          public static void OpenURL (string URL)
      17:          {
      18:              WebDriver.Navigate().GoToUrl(URL);
      19:          }
      20:   
      21:          public static IWebElement FindWebElement(WebItem webItem)
      22:          {
      23:              if (webItem.ID != "")
      24:                  return WebDriver.FindElementById(webItem.ID);
      25:   
      26:              if (webItem.ClassName != "")
      27:                  return WebDriver.FindElementByClassName(webItem.ID);
      28:   
      29:              if (webItem.XPathQuery != "")
      30:                  return WebDriver.FindElementByXPath(webItem.ID);
      31:   
      32:              return null;
      33:          }
      34:   
      35:          public static void Delay(int Seconds = 10)
      36:          {
      37:              System.Threading.Thread.Sleep(Seconds * 1000);
      38:          }
      39:      }


    Основу для выполнения тестов представляет собой экземпляр класса RemoteWebDriver, который предоставляет доступ ко все основным функциям Selenium.  

    При этом, экземпляр класса RemoteWebDriver содержит ссылку на объект драйвера, реализующего работу с конкретным браузером – IE, FireFox, Chrome.

    Таким образом, меняя ссылку на конкретный драйвер мы организуем выполнение скриптов на разных браузерах. В данном примере я использую FireFox.

    Метод OpenURL,как видно из названия предназначен для открытия различного рода ссылок.

    Метод FindWebElement реализует поиск элементов на текущей странице браузера. При этом на вход ему подается экземпляр класса WebItem, который будет описан позднее. Пока лишь отмечу, что этот класс предоставляет возможность работы с элементами на странице.

    Данный метод возвращает экземпляр интерфейса IWebElement, который реализуется всеми страничными элементами Selenium.

    Метод использует возможности поиска объектов на странице по их ID, имени css-класса или запросу XPath. Вообще говоря, Selenium предоставляет больше возможностей поиска, но в данном примере я оставил только эти три, как наиболее часто применяемые.

    Последний метод Delay предназначен для приостановки тестов до момент окончания загрузки страниц.


  3. Создаем класс WebItem, который я упоминал выше.

       1:  public class WebItem
       2:      {
       3:          public string ID;
       4:          public string ClassName;
       5:          public string XPathQuery;
       6:   
       7:          public WebItem(string ID, string ClassName, string XPathQuery)
       8:          {
       9:              this.ID = ID;
      10:              this.ClassName = ClassName;
      11:              this.XPathQuery = XPathQuery;
      12:          }
      13:   
      14:          public void Click()
      15:          {
      16:              TestFramework.FindWebElement(this).Click();
      17:          }
      18:   
      19:          public void SetValue(string Value)
      20:          {
      21:              TestFramework.FindWebElement(this).SendKeys(Value);
      22:          }
      23:      }


    Как видим, это наш собственный класс, который предназначен для работы с элементами на веб-страницах.

    Класс содержит описание способа поиска нашего элемента, а также предоставляет нам возможность задать значение элемента и выполнить нажатие на элемент.


  4. Создаем класс LoginWebItems, который будет содержать набор элементов для работы с формой логина.

       1:  public static class LoginWebItems
       2:      {
       3:          public static WebItem LoginLink
       4:          {
       5:              get
       6:              {
       7:                  return new WebItem("ctl00_Header1_TopHeader1_ExitLinkButton", "", "");
       8:              }
       9:          }
      10:   
      11:          public static WebItem UserNameTextBox
      12:          {
      13:              get
      14:              {
      15:                  return new WebItem("ctl00_ContentPlaceHolder1_EMailTextBox", "", "");
      16:              }
      17:          }
      18:   
      19:          public static WebItem PasswordTextBox
      20:          {
      21:              get
      22:              {
      23:                  return new WebItem("ctl00_ContentPlaceHolder1_PasswordTextBox", "", "");
      24:              }
      25:          }
      26:   
      27:          public static WebItem LoginButton
      28:          {
      29:              get
      30:              {
      31:                  return new WebItem("ctl00_ContentPlaceHolder1_LoginButton", "", "");
      32:              }
      33:          }
      34:      }


    Как видим, класс содержит ссылки на следующие элементы – ссылку на страницу логина, текстовые поля для имени пользователя и пароля, а также непосредственно кнопку логина.


  5. Создадим класс PagesActions, который будет выполнять действия по открытию различных страниц нашего сайта. Он нужен нам для того, чтобы исключить жесткое упоминание ссылок в коде тестовых сценариев.

       1:  public class PagesActions
       2:      {
       3:          public static void OpenHomePage()
       4:          {
       5:              TestFramework.OpenURL("http://www.test.com/");
       6:          }
       7:      }



  6. Теперь создадим класс LoginAction, который будет нам реализовывать действия входа на сайт.

    Впоследствии это действие может быть использовано во многих тест-кейсах.

       1:  public class LoginAction
       2:      {
       3:          public static void DoLogin()
       4:          {
       5:              LoginWebItems.LoginLink.Click();
       6:   
       7:              LoginWebItems.UserNameTextBox.SetValue("test login");
       8:              LoginWebItems.PasswordTextBox.SetValue("test password");
       9:   
      10:              LoginWebItems.LoginButton.Click();
      11:   
      12:              TestFramework.Delay();
      13:          }
      14:      }


    Как видим, наше действие описано простым языком, в понятных терминах и не содержит кода, зависимого от библиотеки, реализующей выполнение скриптов, т.е. от Selenium.


  7. Ну и наконец мы создаем класс тест-кейса LoginTestCase, который реализует непосредственно тестирование входа на сайт

       1:  public class LoginTestCase
       2:      {
       3:          public static void DoTestCase()
       4:          {
       5:              PagesActions.OpenHomePage();
       6:   
       7:              LoginAction.DoLogin();
       8:          }
       9:      }


Таким образом, расширяя впоследствии наши классы, мы можем описывать новые элементы страниц и сами страницы.


Кроме того, мы можем создавать тестовые действия, непривязанные к конкретному инструменту запуска тестов и комбинировать из наших действий тестовые сценарии.


Затем, мы можем использовать наши сценарии в рамках или встроенного unit-тестирования или для тестирования посредством собственного приложения.


Кроме того, мы можем также добавлять дополнительную функциональность для сохранения логов, отчетов, ошибок, замеры времени выполнения тестов и пр.


Мы можем также организовать автоматическое создание багов в TFS – о том, как это сделать я писал в посте “Как создать work item в TFS (Team Foundation Server) из письма в Outlook

P.S.
Другие мои посты на тему Selenium:
1. От QTP к Selenium
2. Создание тестов для Selenium на C# для web-приложений на ASP.NET
Мой сайт - www.msmirnov.ru

понедельник, 23 мая 2011 г. - www.msmirnov.ru

От QTP к Selenium

Последние несколько лет мы использовали Mercury Quick Test Pro (QTP) для выполнения скриптов автоматизированного тестирования наших web-приложений.

В настоящий момент мы осуществляем переход к Selenium. Именно Selenium будет использоваться для выполнения скриптов регрессионного контроля.


Для нас Selenium имеет целый ряд преимуществ по сравнению с QTP:

1. Selenium бесплатный. QTP стоит очень дорого.

2. Selenium позволяет разрабатывать скрипты на том же языке программирования, на котором ведется основная разработка – C#, Java и пр. Это избавляет от необходимости изучать еще один язык программирования для разработки тестовых сценариев. Благодаря этому, разработчики могут при случае легко вносить изменения в тестовые сценарии, а тестировщики избавлены от необходимости переучиваться, при переходе в разработчики.

3. Так как разработка тестовых скриптов ведется в той же среде, что и основная разработка, скрипты Selenium могут использовать библиотеки тестируемого приложения в своих тестах – например, библиотеки бизнес-логики и пр.

4. Тестовые скрипты Selenium можно включать в наборы unit-тестов тестируемого приложения.

5. Разрабатывая тестовые скрипты на Selenium можно создавать дополнительную функциональность, которая требуется в данном конкретном случае – свой логгинг, свою отчетность, замеры времени тестирования и т.п.


Есть, конечно, и некоторые сложности во внедрении Selenium (куда же без них?):

1. Очень бедная документация.

2. Более высокие требования к опыту тестировщиков в плане умений программировать.

3. Полное отсутствие инструментария разработки.

4. Отсутствие возможности тестировать Windows-приложения.

Selenium продукт не новый, но поскольку мы его только осваиваем, в ближайшее время я планирую написать также заметку о том, как вести разработку тестовых скриптов для Selenium на C#.

P.S.
Другие мои посты на тему Selenium:
1. От QTP к Selenium
2. Создание тестов для Selenium на C# для web-приложений на ASP.NET
Мой сайт - www.msmirnov.ru

вторник, 10 мая 2011 г. - www.msmirnov.ru

Заметка о мотивации

Пару лет назад я собирал информацию о теории мотивации в ИТ и не только, а также о практических примерах внедрения различных систем мотивации.

Целью данного исследования было, если возможно, перенять накопленный опыт и применить его в наших условиях.

К сожалению особых результатов, кроме расширения собственного кругозора, это не принесло. Однако сейчас речь не об этом.

С той поры мне всегда интересно послушать про практические примеры внедрения различных систем мотивации в реально работающих коллективах. Особенно мне интересно, если эта система базируется на каких-либо числовых KPI.

И сегодня один мой коллега, имени которого я не называю, рассказал мне о той системе мотивации, которая принята в их ИТ-подразделении.


Суть системы такова: зарплата программистов складывается из двух часть: оклад + премия (50% от оклада).

Для каждой задачи ставится срок ее сдачи. Если программист не сдает задачу во время, то от премии всего ИТ-отдела, во главе с начальником, вычитается 1% за каждый день просрочки.

Если после сдачи задачи в ней будут найдены баги, то аналогично: минус 1% за каждый баг со всего ИТ-отдела.

Как говорит коллега, такого, чтобы отдел получил 100% премии, не было еще ни разу.

Интересная система мотивации, не находите?
Мой сайт - www.msmirnov.ru