Я попытался написать модульные тесты пользовательского интерфейса для своих приложений с графическим интерфейсом, и я столкнулся с проблемой, заключающейся в том, что, хотя они хорошо работают, когда я их первоначально пишу, они оказываются хрупкими и ломаются всякий раз, когда меняется дизайн (то есть довольно часто). Я изо всех сил пытаюсь найти набор руководящих принципов, которые привели бы меня к тому, чтобы иметь поддерживаемые модульные тесты для GUI.
На данный момент я обнаружил, что тесты, говорящие «этот компонент должен где-то показывать свои входные данные», хороши (и это очень легко с HTML). Тесты, проверяющие определенное состояние определенной части компонента, обычно являются хрупкими. Тесты, идущие как щелчок-щелчок-щелчок-ожидание, которые пытаются следовать поведению пользователя и базовой бизнес-логике (которая является наиболее важной частью), обычно оказываются хрупкими. Как мне написать хорошие тесты?
Чтобы быть более точным, я хотел бы знать некоторые шаблоны о том, что я мог бы проверить в моем пользовательском интерфейсе, а не точно, как это проверить. Соглашения об именах и фиксированные идентификаторы хороши, но не решают основной проблемы, которая заключается в том, что GUI сильно меняются. Я хотел бы проверить поведение, которое вряд ли изменится. Как найти правильную вещь для тестирования?
Ответы:
Общая проблема с тестами GUI ... Основная причина, по которой эти тесты считаются хрупкими, заключается в том, что они не могут выдержать изменения в GUI, которые не являются изменением требований . Вы должны стремиться структурировать свой тестовый код таким образом, чтобы изменение в графическом интерфейсе было выделено для одного места в тестах.
В качестве примера рассмотрим тест в следующем виде:
Здесь достаточно места для этого теста, чтобы сломаться, когда вы переделываете интерфейс, даже если требования для проверки остаются.
Теперь давайте поместим это в небольшую альтернативную формулировку:
Тест такой же, требования те же, но этот вид теста переживет модернизацию вашего пользовательского интерфейса. Очевидно, вам нужно будет изменить код, но код будет изолированным. Даже если у вас есть десять или двадцать таких тестов для страницы вашего профиля и вы переместите свою логику проверки, отображающую сообщения об ошибках, например, из javascript-alerts в jquery-popups, вам нужно только изменить одну часть теста, которая проверяет сообщения об ошибках.
источник
Это распространенная проблема. Я бы обратил внимание на:
Как вы называете элементы
Используйте идентификатор или класс CSS для идентификации элементов. Избегайте использования CSS ID, когда объект уникален. Рассмотрим структуру, которую вы используете, например, в Ruby on Rails
name
атрибут назначается автоматически и может (не интуитивно) быть лучше, чем использование идентификатора или класса cssКак вы определяете элементы.
Избегайте позиционных идентификаторов, например,
table/tr/td/td
в пользу форм, таких какtd[id="main_vehicle"
илиtd[class='alternates']
. При необходимости рассмотрите возможность использования атрибутов данных. Еще лучше попытаться избежать тегов компоновки, таких как в<td>
целом, поэтому для вышеперечисленного вы можете либо добавить диапазон и использовать его, например,<span id="main_vehicle">
или селектор подстановочного знака, например,*[id="main_vehicle"]
где*
теперь может быть div, span, td и т. Д.Использование специфичных для теста атрибутов данных , которые используются только для проверки и тестирования.
Избегайте ненужной квалификации для элементов. Вы можете использовать следующее:
body.main div#vehicles > form#vehicle input#primary_vehicle_name
Однако для этого необходимо, чтобы поле ввода оставалось в форме с точным идентификатором транспортного средства и на странице с телом, имеющим класс main, и div с идентификатором транспортных средств, который имеет непосредственный дочерний элемент формы с идентификатором средство передвижения. Любые изменения в любой из этой структуры и тест-паузы. В этом случае вы можете обнаружить, что
input#primary_vehicle_name
достаточно, чтобы однозначно идентифицировать элемент.
Избегайте тестов, которые ссылаются на видимый текст. Текст на странице, который отображается пользователю, обычно изменяется со временем, так как сайт поддерживается и обновляется, поэтому используйте идентификаторы, такие как css id и css class или атрибуты данных. Такие элементы, как
form
,input
иselect
используемые в формах также хорошие части идентифицирующих элементов, как правило , в сочетании с идентификатором или классом, например ,li.vehicle
илиinput#first-vehicle
Вы можете также добавить свои собственные идентификаторы, например<div data-vehicle='dodge'>
. Таким образом, вы можете избежать использования идентификаторов элементов или классов, которые могут быть изменены разработчиками и дизайнерами. Со временем я обнаружил, что лучше просто работать с разработчиками и дизайнерами и прийти к соглашению по поводу названий и областей применения. Это трудно.Как сохраняются фиксированные данные.
Подобно идентификации фактических элементов, старайтесь избегать встроенного жестко закодированного селектора, определяющего значения в пользу объектов страницы - небольших фрагментов текста, которые хранятся в переменных или методах и, таким образом, могут использоваться повторно и также поддерживаться централизованно. Примеры переменных JavaScript, следующих этому шаблону для жестко закодированных значений:
Больше на странице объектов в селене вики и селен документы
Общение с разработчиками.
Независимо от технического подхода с точки зрения «разработчики вносят изменения и нарушают автоматизацию контроля качества», это проблема рабочего процесса. Вы должны убедиться, что: все - одна команда; разработчик запускает такие же интегрированные тесты; стандарты согласованы и соблюдаются обеими группами; определение выполненного включает в себя запуск и, возможно, обновление тестов пользовательского интерфейса; разработчики и тестировщик рассказывают о планах тестирования и посещают обработку заявок (если проводят Agile) и обсуждают тестирование пользовательского интерфейса как часть подготовки. Вы должны убедиться, что любой подход и стратегия, которую вы используете для именования, согласованы с разработчиками приложений. Если вы не попадаете на ту же страницу, вам понравится конфликт по именованию объектов. Некоторые примеры методов объекта страницы, которые я недавно создал для проекта ruby:
Вот те же объекты страницы, что и в переменных javascript:
источник
Причина, по которой люди сначала разрабатывали такие вещи, как MVC, MVP и Presenter, и подобные шаблоны проектирования, заключалась в том, чтобы отделить бизнес-логику от пользовательского интерфейса.
Очевидно, что часть представления может быть проверена только путем запуска программы и проверки того, что она показывает, - другими словами, она может быть проверена только в приемочных тестах.
С другой стороны, тестирование бизнес-логики может быть выполнено в модульных тестах. И это ответ на ваш вопрос. Проверьте все в модели, и если вы можете и хотите, вы также можете проверить код контроллера.
Это может произойти только тогда, когда вы изменили требования. Когда требование изменяется, нет другого пути, кроме как изменить код. Если вам удастся создать хороший дизайн и архитектуру, изменения не распространятся во многих местах.
источник
Тесты взаимодействия с графическим интерфейсом должны быть не более или менее хрупкими, чем любые другие виды тестов. То есть; если ваше приложение каким-то образом меняется, тесты необходимо обновить, чтобы отразить это.
Для сравнения:
Модульный тест
Оригинал :
validateEmail()
должен выдатьInvalidData
исключение. Что правильно отражено в вашем модульном тесте.Изменение :
validateEmail()
должно выдатьInvalidEmail
исключение. Теперь ваш тест неверен, вы обновляете его, и все снова становится зеленым.Тест GUI
Оригинал : при вводе неверного адреса электронной почты появится всплывающее окно с ошибкой, содержащее «Введены неверные данные». Правильно определяется вашими тестами.
Изменение : при вводе недействительного адреса электронной почты будет отображаться внутренняя ошибка, содержащая сообщение «Введен неверный адрес электронной почты». Теперь ваш тест неверен, вы обновляете его, и все снова становится зеленым.
Помните, что вы тестируете входы и выходы - какое-то четко определенное поведение. Независимо от того, является ли это тест GUI или модульный тест или интеграционный тест и т. Д.
источник