Подтвердить что ты не робот

Интеграция автоматизированного веб-тестирования в процесс сборки

Я ищу предложения для улучшения процесса автоматизации функционального тестирования веб-сайта. Вот что я пробовал в прошлом.

У меня был тестовый проект, используя WATIN. Вы эффективно пишете то, что похоже на "модульные тесты", и используйте WATIN для автоматизации браузера, чтобы щелкнуть по сайту и т.д.

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

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

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

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

ДОПОЛНИТЕЛЬНЫЕ ДАННЫЕ Так как люди просили получить более подробную информацию, вот оно. Я запускаю ASP.NET с помощью Visual Studio и Cassini (встроенный веб-сервер). Мои модульные тесты выполняются в MbUnit (но это не так важно. Может быть NUnit или XUnit.NET). Как правило, у меня есть отдельная инфраструктура unit test, которая запускает все мои тесты WATIN. На этапе AssemblyLoad я запускаю веб-сервер и локально копирую код моего веб-приложения.

Меня интересуют решения для любой платформы, но мне может потребоваться больше описаний того, что означает каждая вещь.:)

4b9b3361

Ответ 1

Фил,

Автоматизация просто трудно поддерживать, но чем больше вы используете автоматизацию для развертывания, тем больше вы можете использовать ее для настройки теста (и наоборот).

Честно говоря, проще разработать код автоматизации, факторировать его и реорганизовать его в конкретные, небольшие единицы функциональности при использовании инструмента построения, который не является просто управляя статически скомпилированными, предустановленными модулями функциональности, как в случае с NAnt и MSBuild. Это одна из причин того, что многие люди, которые были относительно ранними пользователями служения, такие как NAnt, перешли к Rake. Свобода обработки кода сборки, как и любого другого кода, - для того, чтобы котинировать его контент и форму, - больше с Rake. Вы не получаете такой же застой в артефактах автоматизации, как легко и быстро с помощью Rake, и гораздо проще script в Rake, чем NAnt или MSBuild.

Итак, часть вашей борьбы по сути связана с инструментами. Чтобы ваша автоматизация была разумной и поддерживаемой, вы должны быть осторожны с препятствиями, которые статические инструменты сборки, такие как NAnt и MSBuild, налагают.

Я бы предположил, что вы не связываете загрузочную ленту тестовой среды с монтажной нагрузкой. Это внутренняя муфта, которая служит лишь для удобства. Там нет ничего плохого (и, скорее всего, все в порядке) с переходом в командную строку и выполнением задачи сборки, которая настраивает среду перед запуском тестов либо из среды IDE, либо из командной строки, либо из интерактивной консоли, например С# REPL из Mono Project или IRB.

Настройка тестовых данных - это просто боль в прикладе. Это нужно сделать.

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

Я управляю всем образцом управления данными из HTTP. Я пишу контроллеры с действиями специально для контроля выборочных данных и выдаю GET против этих действий через Selenium. Я использую их для создания и очистки данных. Я могу составлять GET для этих действий для создания общих сценариев данных установки, и я могу передавать конкретные значения для данных в качестве параметров запроса (или, если необходимо, параметры формы).

Я держу эти контроллеры в области, которую я обычно называю "test_support".

Моя автоматизация развертывания веб-сайта не развертывает область test_support, ее маршруты и сопоставление. В рамках моей автоматизации проверки развертывания я убеждаюсь, что код test_support не находится в рабочем приложении.

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

Существует большое вторичное значение для управления вашими примерами данных веб-приложения или тестовыми данными из Интернета: при демонстрации приложения или при проведении пробного тестирования вы можете создавать сценарии данных, которые вам нужны, просто выдавая некоторые данные против известных (или допустимые) URL-адреса в области test_support. На самом деле делать дисциплинированные усилия, чтобы придерживаться спокойных маршрутов и ориентации ресурсов здесь действительно окупится.

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

Например, запись кода модели домена над семантической моделью ваших веб-страниц поможет создать гораздо более понятный тестовый код и уменьшить хрупкость. Если вы сделаете это хорошо, вы можете использовать те же модели с различными драйверами, чтобы вы могли использовать их в стресс-тестах и ​​тестах нагрузки, а также в функциональных тестах, а также использовать их из командной строки в качестве поисковых инструментов. Кстати, такого рода вещи проще делать, когда вы не привязаны к типам драйверов, как вы, когда используете статический язык. Есть причина, почему многие ведущие аналитики и исполнители тестов работают в Ruby, и почему Watir написан на Ruby. Повторное использование, состав и выразительность намного проще достичь в Ruby, чем в С#. Но эта другая история.

Позвольте догнать когда-нибудь и поговорить о других 90% этого материала:)

Ответ 2

Мы использовали Plasma в одном проекте. Он эмулирует веб-сервер в процессе - просто укажите его в корень вашего проекта веб-приложения.

Это было удивительно стабильно - не копировать файлы и не запускать вне сервера процессов.

Вот как насчет тестирования с помощью Plasma...

    [Test]
    public void Can_log_in() {
        AspNetResponse response = WebApp.ProcessRequest("/Login.aspx");
        AspNetForm form = response.GetForm();

        form["UserName"] = User.UserName;

        form["Password"] = User.Password;

        AspNetResponse loggedIn = WebApp.ProcessRequest(Button.Click(form, "LoginUser"));


        Assert.IsTrue(loggedIn.IsRedirect());

        AspNetResponse homePage = WebApp.ProcessRequest(loggedIn.GetRedirectUrl());

        Assert.AreEqual(homePage.Status, 200);
    }

Все классы "AspNetResponse" и "AspNetForm" включены в Plasma.

Ответ 3

В настоящее время мы используем автоматизированный процесс сборки для нашего приложения asp.net mvc.

Мы используем следующие инструменты:

  • TeamCity
  • SVN
  • NUnit
  • Селен

Мы используем msbuild script, который работает на агенте сборки, который может быть любым количеством машин. Msbuild script получает последнюю версию кода из svn и строит ее.

В случае успеха он затем развертывает артефакты в данной машине/папке и создает виртуальный сайт в IIS.

Затем мы используем задачи MSBuild contrib для запуска sql-скриптов для установки базы данных и загрузки данных, вы также можете сделать восстановление.

При успехе мы запускаем тесты nUnit. Настройка теста гарантирует, что селен работает и работает, а затем проводит тесты на селен так же, как это делает Ватин. Selenium имеет хороший рекордер для тестов, которые можно экспортировать в С#.

Хорошо, что в Selenium вы можете управлять FF, Chorme и IE, а не ограничиваться IE, что было в случае с Watin в последний раз, когда я смотрел на него. Вы также можете использовать Selenium для тестирования нагрузки с помощью Selenium Grid, поэтому вы можете повторно использовать те же тесты.

При успешном выполнении msbuild затем теги сборки в svn. У TeamCity есть работа, которая выполняется за одну ночь, которая будет развертывать последний тег в промежуточной среде, готовой для бизнес-пользователей проверить статус проекта на следующее утро.

В предыдущей жизни у нас были сценарии nant и msbuild для полного управления средой (установка java, selenium и т.д.), однако это занимает много времени, так как pre req мы предполагаем, что каждый агент сборки установил эти установки. Со временем мы включим эти задачи.

Ответ 4

Зачем вам нужно копировать код? Ditch Cassini и позволить Visual Studio создать для вас виртуальный каталог. Конечно, разработчики должны помнить, чтобы создавать перед запуском веб-тестов, если веб-приложение изменилось. Мы обнаружили, что это не имеет большого значения, особенно если вы запускаете веб-тесты в CI.

Данные - большая проблема. Насколько я вижу, вы должны выбирать между несовершенными альтернативами. Вот как мы справляемся с этим. Во-первых, я должен объяснить, что мы работаем с большим сложным унаследованным приложением WebForms. Также я должен упомянуть, что код домена не подходит для создания тестовых данных из тестового проекта.

Это оставило нам пару вариантов. Мы могли: (а) запустить сценарии установки данных в сборке или (б) создать все данные через веб-тесты с использованием фактического веб-сайта. Проблема с опцией (а) заключается в том, что тесты становятся связанными со сценариями на минутном уровне. Это заставляет меня задуматься о синхронизации веб-тестового кода с T-SQL. Итак, мы пошли с (б).

Одним из преимуществ (b) является то, что ваша настройка также проверяет поведение приложения. Проблема в том, что... время.

Идеально тесты должны быть независимыми, без временной привязки (могут выполняться в любом порядке) и не использовать какой-либо контекст (например, общие тестовые данные). Общий способ справиться с этим - настроить и снести данные с каждым тестом. После некоторой осторожной мысли мы решили нарушить это правило.

Мы используем Gallio (MbUnit 3), который предоставляет некоторые интересные функции, которые поддерживают нашу стратегию. Во-первых, он позволяет указать порядок выполнения на уровне прибора и теста. У нас есть четыре "установочных" светильника, которые упорядочены -4, -3, -2, -1. Они выполняются в указанном порядке и перед всеми "незастроенными" светильниками, которые по умолчанию имеют порядок 0.

Наш веб-проект зависит от сборки script только для одного: одного известного имени пользователя/пароля. Это связь, с которой я могу жить. По мере запуска тестов установки они создают объект "контекст данных", который содержит идентификаторы данных (компании, пользователи, поставщики, клиенты и т.д.), Которые впоследствии используются (но никогда не меняются) во всех других светильниках. (По идентификаторам я не обязательно имею в виду ключи. В большинстве случаев наш веб-интерфейс не предоставляет уникальные ключи. Мы должны перемещаться по приложению, используя имена или другие прокси-серверы для истинных идентификаторов. Подробнее об этом ниже.)

Gallio также позволяет вам указать, что тест или приспособление зависит от другого теста или приспособления. Когда прецедент терпит неудачу, зависимый пропускается. Это уменьшает зло временного сцепления, предотвращая "каскадные сбои", которые могут получить много путаницы.

Создание базовых данных теста один раз, а не перед каждым тестом, ускоряет работу. Тем не менее, тесты настройки могут занять 10 минут. Когда я работаю над новыми тестами, я хочу запустить их и повторить их часто. Введите еще одну крутую функцию Gallio: Ambience. Ambience - обертка вокруг DB4, которая обеспечивает очень простой способ сохранения объектов. Мы используем его для автоматического сохранения контекста данных. Таким образом, тесты установки должны выполняться только один раз между перестройками базы данных. После этого вы можете запускать любые или любые другие приборы повторно.

А как насчет очистки тестовых данных? Разве нам не нужно начинать с известного состояния? Это правило, которое мы сочли целесообразным сломать. Стратегия, которая работает для нас, заключается в использовании длинных случайных значений для таких вещей, как название компании, имя пользователя и т.д. Мы обнаружили, что не сложно провести пробный прогон внутри логического "пространства данных", чтобы он не ударялся в другие данные. Конечно, я боюсь того дня, когда я трачу часы, преследуя неудачный тест phantom, только чтобы обнаружить, что это столкновение данных. Это компромисс, который работает для нас в настоящее время.

Мы используем Ватина. Мне это очень нравится. Еще один ключ к успеху - это то, о чем упоминал Скотт Беллволл. Когда мы создаем тесты, мы создаем абстрактную модель нашего пользовательского интерфейса. Поэтому вместо этого:

browser.TextField("ctl0_tab2_newNote").TypeText("foo");

Вы увидите это в наших тестах:

User.NotesTab.NewNote.TypeText("foo");

Этот подход обеспечивает три преимущества. Во-первых, мы никогда не повторяем магическую строку. Это значительно снижает хрупкость. Во-вторых, тесты намного легче читать и понимать. Наконец, мы скрываем большую часть структуры Watin за нашими собственными абстракциями. Во втором примере только TypeText является методом Watin. Это упростит изменение при изменении структуры.

Надеюсь, что это поможет.

Ответ 5

Было сложно, но не невозможно, построить этап интеграции в процесс сборки с помощью maven. Случилось так:

  • Игнорировать все тесты JUNit в конкретном каталоге, если не запускается фаза интеграции.
  • Добавьте профиль maven для выполнения тестов интеграции.
  • Для этапа тестирования перед интеграцией -

  • Запустите Jetty, запустив приложение, попавшее в тестовую базу данных.

  • Запустить сервер selenium
  • Провести тесты интеграции селена на этапе интеграции.
  • Остановить сервер селена
  • Остановить селен

Трудность в этом шаге действительно создала пристань - мы не могли заставить ее просто начать войну, поэтому нам действительно нужно, чтобы причал распаковывал войну, а затем запускал сервер, но он работает, ну и автоматизирован - все, что вам нужно сделать, это ввести mvn -PintegrationTest (это было наше имя профиля тестовой интеграции) и от него.

Ответ 6

Вы имеете в виду автоматическое начало тестирования после завершения сборки? Вы можете написать автоматические сценарии, чтобы скопировать файлы сборки в рабочий IIS, пока сборка прошла успешно. А затем запустите автоматический BVT по вызову mstest.exe или другими методами.

Вы можете попробовать с помощью autoitx или некоторого языка функций, такого как Python, ruby.