Структура и организация тестов (Аннотация @Test)

Согласен, если комплексная, то это вполне нормально. Как пример, могу привести свой последний проект, где тесты проверяют выгружаемые XML-файлы. В тесте делается минимум две проверки:

  1. на количество выгружаемых файлов (в разных кейсах может быть выгружено различное количество)
  2. на содержимое файлов

Несмотря на то, что формально проверок 2, но это части единого теста, при провале любой из них тест считается проваленным.

То есть правило “один тест - одна проверка” надо воспринимать не буквально, а с оглядкой на тестируемый функционал и структуру тестов

Кстати в ответ на пример.

step.input_user_name(TestUtils.randomUserName());
step.input_password(user.getProperty("Password"));

Хотел бы такую вещь спросить, вот у меня есть 500 элементов (каждый имеет 1 из 4 типов), судя из примера, нужно писать 500 методов? (Имя, Номер, Страна)

В своем методе я очень сомневаюсь, так как если взять пример текстового поля:

card.edit(textField.name,"123");

То в уроках говорится, что не надо обращаться к элементам напрямую.

Взять другой метод

card.edit("Имя","123");

Но опять же, мы обращаемся непосредственно к имени поля (хоть внутри метода у нас используется правильный локатор). Тоже как то странно выглядит.

Подскажите, как должна выглядеть например, строка редактирования поля и чекбокса в главном тесте, учитывая, что полей и чекбоксов (500 штук). Описание метода мне не нужно, именно сама строка в тестах. Спасибо.

P.S. извините новичка за нубские вопросы =)

подгружать разные файлы либо SQL подключить для

я что-то в вопросе запутался…

если нужно проверить всё за раз - в одном
если нужно для каждого случая отдельно - туча тестов

Провокация.
Что до ваших примеров, еще раз повторюсь, такая реализация будет создавать больше вопросов и проблем, нежели профита.

1 лайк

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

В общем, если используется PageObject, рекомендуется не обращаться к полям напрямую в коде теста.

Тем более, есть обходные пути. Например, хранить состояние контролов в специальном классе (называется Data Transfer Object). Обсуждение можно почитать тут:

А тут я постарался собрать заметки по Пейджобжектам: SWD.Starter/methodology_all_in_one_rus.md at master · dzharii/SWD.Starter · GitHub

Но, это лишь рекомендация. Т.е. правило, которое иногда можно нарушить.

Если вы объявляете и используете веб-элементы непосредственно внутри теста, то на этот случай такая рекомендация не распространяется.

@mindjin, у вас всего 500 полей и чекбоксов в приложении, распределенных по разным страницам или все на одной странице?

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

http://pencil.evolus.vn/

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

В общем, если форма большая – то с ней всегда много рутинной работы.
Если в форме на одной странице действительно 500 полей – то и методов доступа, учитывая что нужен метод для установки и получения значения, может быть 1000.

Я бы хотел уточнить, именно на той странице, которая на скриншоте, действительно 500 элементов? Они все состоят в одном логическом блоке, или разделены на несколько логических блоков?

Нее я имел ввиду 500 элементов по всей админке учитывая разный Id. Поэтому очень интересует обращение к ним через тест.

А в чем польза этих 1000 геттеров/сеттеров? Стоит ли, так буквально, переносить все “правила хорошего тона” программирования на автоматизацию?
Пусть есть еще DTO - 500 филдов+1000 геттер/сеттер. Итого 500+1000+500+1000=3 000 филдов и методов для 500 реальных сущностей. С моей точки зрения, у автоматизации основная цель это отдача (КПД), а у этих 2000 методов она равна нулю.

Так предложите как будет задаваться обращение к полю и изменение его через сам тест? Я просто жду конкретного ответа чтобы исправить свой Framework.

P.S. Сейчас реализация например с попапами такая.

card.popup("Видеофильм", "Маруся") //попап сам определит какой это вид элемента, а также переключится на самый последний попап и применит к нему значение, в данном случае это текстовое поле

card.popup("Возраст", "+3") //это уже Dropbox

card.popup("Скидка", "on") //это Checkbox

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

Начнем с простого. Глядя на следующий код:

кто сможет ответить на вопрос: что собственно ваш тест тестирует? Абстрактные попапы какой-то мистической карты? Какие попапы? Алерты? Нотификейшены? Какой карты? Игральной? Гугл мэпс? Или может это профиль юзера? Тест должен отражать логику тестируемого сценария. Ваши 3 строки - это 3 компонента различных сущностей: Movie, User, Discount. Вы во всех своих примерах плюете на 4 фундаментальных концепции: OOP, DDT, PageObject, DSL. Любите функциональное программирование? Пишите на Scala. Плевать на основные концепции? Напишите свой DSL для автоматизации.

По теме:

configPage()
      .fillInMovieInfo(movie)
      .fillInUserInfo(user)
      .fillInDiscountInfo(discount)
      .submit();

Как заполнить поля на основании переданных данных - уже забота страницы, но уж никак не теста. Хотите нечто generic? Хотите избавиться от миллиона геттеров? Придумайте способ маппинга инкапсулированных элементов страницы + напишите generic verification модуль. Как это сделать? Out of scope данной темы.

О каком готовеньком решении идет речь, вы о чем вообще? Если бы внимательно прочитали тему, я твердо сказал, что мне не нужны готовые решения. Сначало остановился на Getter&Setter, но были сомнения. Я вас не прошу писать за меня код. Я прошу как новичку в программировании дать совет, что использовать (в крайнем случае что почитать)

P.S. например о геттерах и сеттерах я вообще только из этого форума узнал. Например реализация в одной из ссылок, очень интересная:

textField("Last Name").type(lastName);
    textField("Phone").type(phone);
    textField("Email").type(email);
    textField("Username").type(userName);
    textField("Password").type(password);
    textField("Password again").type(password);
    dropDownList("User Type").select(userType);
    dropDownList("Reporting Level").select(reportingLevel);
    checkbox("I agree").check();

но пока не совсем понимаю как она работает.

Все конкретные ответы зарыты в поиске данного форума.

  • Концепции ООП.
  • PageObject:
  • Архитектура:

Реализация конкретных html elements (textField, dropDown, checkbox), у который есть свой уникальный набор методов. Доступ осуществляется по имени, а в методы передается конкретный набор данных. При этом page elements все еще являются частью page object. Т.е. они встраиваются в страницу при помощи композиции.

Вот еще видео от Николая Алименкова, где четко описаны основные ошибки начинающих автоматизаторов и как должен выглядеть хороший тест:

Если для вас и его мнение - не показатель, то уж извините.

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

textField("Last Name").type(lastName);

type(lastName) - это обращение к WebElement’у?

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

Я прочитаю и посмотрю, то что вы выше ответили. Но вопросы я скорее задавал просто от недостатка самой информации, поэтому и повторялся. Еще раз спасибо. P.S. и нет, меня не задело ваше обращение =)

type - метод объекта textField, куда вы передаете данные, которые нужно ввести.
Сам textField - универсальный элемент; не знаю, как он внутри реализован, но смею предположить, что в момент передачи стринги “Last Name”, осуществляется поиск элемента по заданному имени; либо локатор формируется динамически, либо элементы замаплены внутри. Тем самым, вы получаете возможность обратиться к элементу по ключу.

Ну, как выяснилось в посте выше, всего в админке 500 филдов, а не на отдельной странице.
Вверху поста я вижу скриншот, где я насчитал 30 полей. Тут я бы создал отдельный Data Transfer Object (MovieData) с тридцатью полями, а саму страницу описал бы как PageObject – EditMoviePage.

В EditMoviePage я бы создал два дополнительных метода:

void fillForm(MovieData data);
MovieData readForm()

которые устанавливают значения согласно данным DTO и читают эти значения соответственно.

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

В класс MovieData я бы добавил статический метод getDefault(), который бы заполнял поля формы правильными рандомными данными (или как вариант строка + текущая дата). Таким образом, тест мог бы выглядеть так (псевдокод):

MovieData expectedData = MovieData.getDefault();
editMoviePage.fillForm(expectedData);

editMoviePage.save();
editMoviePage.close();

manageMoviesPage.open(expectedData.name);

MovieData actualData = editMoviePage.readForm();

verifyData(expectedData, actualData);

verifyData(expectedData, actualData);

Я тут специально не использовал asserAreEqual для двух объектов, потому что во многих фреймворках нет такого стандартного метода, который бы проверил каждое поле expected на соответствие actual.

Чтобы не проверять каждое поле отдельно мы можем переопределить метод toString() в классе MovieData, который бы возвращал строку со всеми полями объекта:

title: "Hello world" \n
rating: 5\n
...

таким образом, при помощи DTO можно проверить все 30 полей одной командой как текстовую строку.

методы работы с конкретными полями

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

С большими формами на > 20 полей будет много рутинной работы. Зато, с маленькими формами – такой работы будет значительно меньше. Можно обойтись и без сеттеров, но тогда в коде теста, вместо

somePage.fillName("Hello")

будет дополнительный код по типу:

somePage.name.clear();
somePage.name.sendKeys("Hello");

как по мне, лучше эти строки спрятать внутри сеттера.

2 лайка