lesha писал(а):Я вот что думал... Первый вариант, если честно, мне нравится больше
. Вот почему: тестовые скрипты тогда будут достаточно читабильны. Т.е. почти случай тестирования ключевыми словами: Залогиниться() -> Открыть Спсиок Пользователей()-> СоздатьПользователя() -> ПроверитьЕстьЛиПользователь(). Во втором случае скрипты будут сложнее, и более похожи на записанные с помощью рекордера. Но, возможно, более гибкими и устойчивыми к изменениям.
Интересен также вопрос о поддержки кода певого и второго вариантов.. Идеи?
Да, ты прав насчет того, что при первом варианте тесты будут достаточно читабильны. Возможно также, что во втором случае скрипты будут более гибкими и устойчивыми к изменениям.
Но я считаю по своему, хоть и небольшому пока опыту автоматизации тестирования, что сила заключается в комбинации этих двух методов, так называемая "золотая середина".
Это надо делать для того, чтобы с одной стороны у нас в скрипте были ассоциативно понятные функции ("ключевые слова"), с другой стороны, чтобы эти скрипты были устойчивыми и легко поддерживались.
Для этого необходимо, чтобы фреймворк базировался на понятии модульности и содержал многоуровневую структуру скриптов.
Под модульностью понимается вызов одних функций из других; или использование результата выполнения одних функций как входных данных для других.
Что я имею ввиду под многоуровневой структурой скриптов? А я имею ввиду следующее.
На самом высоком уровне (уровень Test Case) мы выполняем действия с приложением вызывая асооциативно понятные функции:
- ДобавитьПользователя(имя, фамилия, мейл)
- ПроверкаЕстьЛиПользовательВСписке(мейл)
- УдалитьПользователя(мейл)
Можно представить, что под этими функциями на уровне интерфейса понимаются вполне конкретные действия (такие действия, которые тестировщик выполняет, если ему скажут, например, надо проверить "Добавление Пользователя").
Например, "ВызватьФормуСоздания()", "ЗаполнитьФормуСоздания()", "ЗасабмититьФорму()"
Т.е. получается, что функция ДобавитьПользователя(имя, фамилия, мейл) будет соответственно вызывать функции на один уровень ниже, а именно:
- "ВызватьФормуСоздания()"
- "ЗаполнитьФормуСоздания(имя, фамилия, мейл)"
- "ЗасабмититьФорму()"
Эти функции могут вызывать функции еще более нижних уровней, но в конце концов мы доходим до уровня элементарных функций (действий) скриптового языка или самого средства атоматизированного тестирования.
В данном случае функция "ВызватьФормуСоздания()" может выполнять уже элементарые действия такие как НажатьНаКнопку(), ПерейтиПоСсылке() и т.д.
Т.е. получается такая структура:
- Код: выделить все
ДобавитьПользователя(имя, фамилия, мейл){
ВызватьФормуСоздания();
ЗаполнитьФормуСоздания(имя, фамилия, мейл);
ЗасабмититьФорму();
}
ВызватьФормуСоздания(){
ПерейтиПоСсылке("members");
НажатьНаКнопку("add_member");
}
ЗаполнитьФормуСоздания(имя, фамилия, мейл){
....
}
ЗасабмититьФорму(){
....
}
ПроверкаЕстьЛиПользовательВСписке(мейл){
....
}
УдалитьПользователя(мейл){
....
}
Что мы получаем в результате такого построения скриптов?
С одной стороны, на самом высоком уровне, да и на нижних скрипты достаточно читабильны и понятны, а с другой - при такой структуре скрипты являются гибкими и устойчивыми.
При изменении в тестовом приложении, нужно будет внести изменения в скриптах нижних уровней, в определенных функциях, а все остальные функции на более верхних уровнях будут работать без изменений, так как используют функции нижних уровней.
Как видно, например, если изменится расположение формы создания мемберов, то вносятся изменения только в функцию ВызватьФормуСоздания(), после этого все остальные функции остаются работоспособны.
Единственным минусом такого подхода, является то, что для ускорения написания скриптов нам мало в чем поможет автоматический Record script (все надо руками писать).
Конечно этот подход требует много времени на разработку скриптов и самого фреймворка, но легкость поддержки таких скриптов на больших проектах, где часто меняется тестовое приложение может оправдать затраты времени на написание самих скриптов.
Прошу комментарии...