Введение
Всем Buenos Dias! В своей статье я хотел бы максимально лаконично и просто рассказать о том, как построить процесс автоматизированного тестирования web-приложения с нуля. Первым делом нужно правильно расставить приоритеты и выбрать приемлемое соотношение цена/качество. Сразу определимся — это будет не решение «на коленках» из зоопарка скриптов, которыми часто пользуются при ручном тестировании. В тоже время мы не будем тратить много усилий на проектирование нашего «фреймворка» для автоматизации. Наша цель — предоставить результаты своей бурной деятельности перед руководством в максимально короткие сроки, при этом система должна быть:
- максимально простой, чтобы тесты могли писать даже специалисты по ручному тестированию
- гибкой и расширяемой, поскольку мы не можем адекватно оценить весь объем работ на данном этапе
- кроссплатформенной (Selenium WebDriver C# поддерживает Firefox, Chrome и IE)
В своем примере я буду успользовать .NET (Microsoft Unit Testing Framework) и Selenium WebDriver C#.
Поехали
Итак, первым делом необходимо отобрать некоторое количество тестовых сценариев высокого приоритета, но довольно простых.
Далее создадим в студии новый solution. Вполне логично будет создать в нем 3 проекта: тесты, описание страниц и утилиты. Это и будут наши три базовые сущности.
Схема будет довольно простая: тест работает со страницами, запрашивая на них какие-либо данные или выполняя там какие-либо действия. В утилитах мы разместим классы, которые будут отвечать за работу c браузером и web-элементами на страницах посредством Selenium WebDriver. Вполне логично написать обертки (wrapper), поскольку Selenium WebDriver API имеет множество недостатков и может показаться довольно неудобным. Именно в этих обертках мы инкапсулируем (спрячем) весь специфический и некрасивый код. Для примера, создадим классы Browser и WebElement, которые предоставят разработчикам автотестов только тот футкционал, который им нужен. В дальнейшем я хотел бы описать этот процесс в отдельной статье, поэтому не буду останавливаться.
Тесты
Определимся с тем, что будут представлять собой наши тесты. Не будем изобретать велосипед — в идеале тест состоит из 4 частей:
- входные (тестовые) данные
- предусловие, т.е. некоторое состояние системы, при котором мы сможем выполнить необходимую проверку
- взаимодействие с web-приложением
- проверка — сравнение ожидаемого результата с полученным. В MS Unit Testing Framework для этого существует отдельный класс Assert
При этом важно обеспечить атомарность тестов — тест должен проверять одну логическую операцию и в идеале иметь одну единственную проверку. Плюсы данного подхода следующие:
- сокращение времени анализа результатов тестов
- не нужно тратить время на реализацию масштабного логирования (не стоит забывать, что MS Unit Testing Framework умеет собирать всевозможную диагностическую информацию в процессе выполнения теста, например: стэк вызовов, лог событий, IntelliTrace, запись фото и видео, анализ кодового покрытия)
Описание web-страниц тестируемого продукта
Что же будут представлять из себя описания страниц?
Во-первых, это описания элементов, с которыми мы будем работать, т.е. способ распознавания их по id, классу, имени, xpath и др. Не надо описывать сразу все имеющиеся на странице элементы, это нерациональная трата времени. При этом все эти описания должны быть приватными и не выходить за рамки класса страницы.
Во вторых, страница будет содержать свойства (getters) и методы, с помощью которых тесты смогут получить информацию со страницы, например значение какого-нибудь текстового поля.
И в третьих, страница будет содержать методы для совершения действий на самой странице, например клик по кнопке. Важно отметить, что описание страницы не должно содержать никакой логики и никаких проверок! Проверки должны быть в тестах. И в то же время, здесь не должно быть никаких вызовов Selenium WebDriver API.
Утилиты
В данном проекте, как минимум, будут находится обертки над Selenium WebDriver API. В последствии это место станет скоплением всевозможных helper’ов, утилит, расширений и т.д. до их вынесения в отдельные сущности и проекты.
Заключение и пример
Таким образом, нужно четко разграничить логику наших автотестов, для этого мы и создали три отдельных проекта. Я не исключаю, что в процессе развития проекта появятся и другие логические уровни со своими сущностями, но минимум будет такой.
Далее я покажу один простой пример и на этом закончу статью. Если она окажется интересной, я обязательно напишу продолжение, где опишу детали реализации тестов, страниц и оберток над WebDriver API.
[TestClass] public class LogOnTests : TestsBase { [TestMethod] public void LogOnWithEmptyLogin() { #region TestData const string login = null; const string password = "password"; const string error = "Empty login!"; #endregion Browser.Open(...); LogOnPage.LogOn(login, password); Assert.AreEqual(error, LogOnPage.Error, "Error expected."); } } public static class LogOnPage { private static readonly WebElement LoginEdit = new WebElement().ById("Login"); private static readonly WebElement PasswordEdit = new WebElement().ById("Password"); private static readonly WebElement LogOnButton = new WebElement().ById("LogOn"); private static readonly WebElement LogOnValidationError = new WebElement().ById("LogOnValidation"); public static void LogOn(string login, string password) { LoginEdit.Text = login; PasswordEdit.Text = password; LogOnButton.Click(); } public static string Error { get { return LogOnValidationError.Text; } } }
P.S. Вспомнилась старинная русская поговорка: кто рано встает, тот отлаживает тесты.
ссылка на оригинал статьи http://habrahabr.ru/post/178321/
Добавить комментарий