Подскажите как пофиксить 1) Cannot deserialize object because no JSON deserializer found in classpath. Please put Jackson (Databind), Gson, Jackson, or Yasson in the classpath. 2) no suitable method found for extracting(UserPojoFu[...]Email)
Видео просто потрясающее: в рунете я просто ничего похожего не смог найти. Единственное что мне как новичку приходится данное видео пересматривать по несколько раз, т.к. концентрация полезной информации на одну секунду повествования крайне велика. Пожалуйста, продолжайте свою деятельность. Уверен, что незаслуженно малое количество просмотров в будущем скорректируется в большую сторону.
Друг, ты действительно красавчик! Единственное - попробуй в начале, середине и конце видео напоминать смотрящим, чтоб подписывались, тогда дела пойдут сильно лучше... Народ забывает + не знает, что это важно. Жду следующего видео! Было бы круто, если расскажешь про построение апи с нуля... А-ля имеем сервис, в нем несколько рабочих апишек и какая-нибудь небольшая интеграция, например для получения токена, который используется у нас в запросах. Интеграцию можно глушить или не глушить.. Да или просто без интеграций.. Еще идеи для видео: - Заглушки. Как глушить, как настраивать. - Тестовые данные в виде фабрик для сквозных тестов(happy path). Подумать над ddt, держим пул данных и генерим рандом фабрику из пула - Передача в запросы JSON-файлов. - Паттерны для API тестирования.
Чувак, ты реально крут! Ты так просто и понятно с примерами всё объясняешь, что становится реально понятно, как это работает. Я за пару часов просмотра твоих роликов уяснил для себя больше полезной и нужной мне инфы, чем за несколько дней поиска и просмотра других авторов. Не забрасывай это дело. У тебя очень хорошо получается объяснять. Информации в Интернете много, но толково объяснить её могут единицы.
Спасибо за простоту объяснения, грамотность и нужный материал. Отдельный плюс за голос, который прямо успокаивает и вселяет уверенность, что все просто и все получится)
Просто супер видео, настолько сжато и доступно все разложено. Плюс еще ломбок и билдер, есть что посмотреть начинающему и не только. Отдельное спасибо за ускоренное видео в момент написания кода
Оч крутой контент! Автору однозначно лайк! Не задумывались курсы проводить или взять людей на платный менторинг? С радостью бы занял одно из мест ради таких глубоких объяснений.
С последних 10 минут скорость добавления нового кода сильно увеличилась, а с последних 5 минут немного жесть началась в плане изменений и скорости их имплементации :( Но, не смотря на это - контент ТОП!
Осилил за два дня, переписал себе весь код в нескольких классах и "этапах", которых у Вас в исходном коде не осталось Опять же, потрясающий труд, спасибо огромное. Я очень надеюсь суметь адаптировать полученные знания под свои автотесты. Буду очень признателен, если подскажете: Я сейчас работаю над автотестами (поднимаю все с нуля), которые вынужден буду запускать в чужой системе, а именно - на основе Jira( наши продукты - это надстройки на неё). Хочу сократить издержки по времени необходимые на прогон теста, путем использования вместо методов, вызываемых через UI-интерфейс Jira, предоставляемые ими API. То есть логины, заполнение полей и так далее делать не селениумом/селенидом, а Rest запросами Скажите, оптимально ли подобным образом комбинировать передачу информации в запросах, при написании UI-автотестов? Типа инфраструктура на API, а UI тесты - на интерфейсах. Не сильно ли это также усложняет архитектуру тестов?
Да, я сам пропагандирую такой подход: стараться делать, насколько это возможно, вспомогательные действия через api, а через ui только непосредственно проверяемые шаги. А в идеале в принципе большую часть функционала проверять именно через api, тесты чисто на ui перенести в юнит тесты, а в функциональных ui тестах оставить только небольшой смоук или проблемные места именно связанные с UI
Мда, респект тебе, автор. Набрать 28000 просмотров на видео про Жабу - это сильно) Я теперь не удивляюсь, что автотестеры получают в месяц как я за полгода. Блииин, какая трешатина. И синтаксис Джава ужасно ужасный. Но.... ))))
@@simple_automation Спасибо за ответ. Я руками тестирую. Получил задачу потихоньку автоматизировать. Стек Java, TestNG, Rest assured. 1. Интересует каркас боевого проекта автотестов. 2. Более боевой пример @DataProvider (или что вместо него). 3. Несколько тестовых стендов: как лучше сделать path генератор, чтобы урлы стенда были в конфиги или в классе константами прописать?
@@ДамирИ-ы7ж про типично структуру тестового фреймворка и testng планируется отдельное видео. Для конфигов я обычно использую typesafe библиотеку, про это рассказывал тут ruclips.net/video/YD7sjAO0BLY/видео.html , для разделения по стендов просто выношу в корень конфига название стенда и вот так выглядит метод создания конфига в фабрике private TestConfigFactory(){}
Да, форма подачи подразумевает отсутсвие длинных пауз и лишней воды, что бы каждый мог подобрать под себя скорость и не нужно было при это чего-то перематывать. Так же подразумевал, что при необходимости видео можно остановить и посмотреть нужный кусок кода или пересмотреть несколько раз.
Вы использовали pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ, но в formatter уже DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); Вот эта выделенная "Z" зачем? Я попробовал сделать как в паттерне, но тогда ошибка о невозможности распарсить- ошибка на 24 символе (index 23). Аналогичный результат, если убрать "Z" из десириалайзера вообще. Можете пожалуйста пояснить?
Z означает таймзону, точнее нулевой оффсет относительно UTC. Если добавить апостроф или кавычки(зависит от парсера), то это уже будет просто буква, то-есть элемент форматирования как символы - и : например. И обратите внимание, что вокруг Z именно одинарные кавычки, как вокруг T. А есть еще какой-то текст в ошибке, стэктрейс?
@@simple_automation Текст ошибки, если в formatter убрать кавычки вокруг Z: сom.fasterxml.jackson.databind.JsonMappingException: Text '2022-12-01T22:50:21.671Z' could not be parsed at index 23 (through reference chain: pojos.CreateUserResponse["createdAt"]) java.lang.RuntimeException: com.fasterxml.jackson.databind.JsonMappingException: Text '2022-12-01T22:50:21.671Z' could not be parsed at index 23 (through reference chain: pojos.CreateUserResponse["createdAt"])
Присоединяюсь ко всему нижесказанному - поток информации зашкаливает, но это и круто. Скажите, пожалуйста, планируется ли ролик по возможности работы rest-assured с soap сервисами? спасибо
Спасибо за видео, очень помогло. По Вашему мануалу все получилось, но у меня по моему тесту есть вот такая проблема.. мне в body надо передать такое "headers":{"accept":"application/json","WAREHOUSE-TEST":"1"}, и вот куда бы я его не писал, и в поджо класс запроса и в сабо body теста и в спеку везде отдает одну и ту же ошибку error": { "message": "Validation error.", "additional": { "fieldName": "WAREHOUSE-TEST", "message": "Header parameter is not passed.", "bindings": [ Помогите плиз что я не так делаю( Если я запрос передаю весь стрингой тогда проходит все без ошибок и ответ правильный. Заранее спасибо.
Видео информативное, но так как написано, что автоматизация с нуля, ускорения не дают времени понять ничего... придется раз 10 пересмотреть из-за перемоток
в целом это зависит от десериализатора, канонинчые фреймворки часто создают объект конструктором без аргументов и все значения устанавливают сеттерами, но бывает, что и просто конструктор со всеми аргументами подходит
Спасибо большое за столь приятное объяснение ! Еще очень хотелось бы посмотреть что-то про polling API, как избавиться от Thread.sleep в ожидании ответа от сервера. Знаю, что для этих целей используют метод org.awaitility.Awaitility, но он работает в другом потоке, и вызывает проблемы с сеансом. Может существуют более простые способы ?
Если я правильно понял и имеется ввиду ожидание конкретного ответа от сервера, то я обычно использую retry helper, что-то вроде codeshare.io/qPPdwM . Либо вместо таймаута обычно передают количество попыток. Проблемы же с сеансом можно тоже обычно решить, добавив логику повторной авторизации/рефреша токена или как у вас там сеансы создаются. Как-нибудь расскажу про это поподробнее
@@simple_automation Спасибо за ответ! Если не трудно, покажите, пожалуйста, пример вызова waitResult (codeshare.io/qPPdwM) например для апи : public TicketsResponse getTicketsResponse(String APP_URL, String token, Object request) { return given().spec(REQ_SPEC) .header("Authorization", "Bearer " + token) .body(request) .when() .post(APP_URL + "api/v2/tickets") .then().statusCode(200) .log().body() .extract().body().jsonPath().getObject("", TicketsResponse.class); } Что нужно передать в функцию, чтобы дождаться ответа 200 ?
@@annabelousova7596 вам нужен метод, который будет возвращать код ответа. Если вы это делаете для всех запросов, то лучше это сделать прямо в классе с запросами как метод обертку. Но я бы ждал скорее не код ответа, а что-то в теле ответа или что он будет не null. Допустиим, метод getTicketsResponseCode будет возвращать именно код ответа, тогда используется так waitResult(() -> getTicketsResponseCode(URL, token, request), 200, 5)
Привет Самый полезный контент, который я видел. Спасибо большое! Не совсем понял один момент: UsersSteps теперь не нужен? Ведь все методы были перенесены в сервисы (но сам класс UsersSteps остался).
День добрый, методы сервисов часто дальше группируются в еще более высокоуровневые степы. Например, в рест сервисе может быть 3 метода создать локацию, компанию и офис. И эти 3 метода можно объединить в один степ создать офис, если это часто делаете.
Хорошая подача, спасибо=) Скажи, пожалуйста, что думаешь по поводу того, что аннотации в Java работают через рефлекцию, что в свою очередь сказывается на производительности, стоит оно того в угоду тому, что вы не хотите видеть геттеры и сеттеры?)
Спасибо:) Если это не разработка для устройств вроде умных часов или фитнес трекеров, то накладные расходы в наше время уже совсем не существенны(а если для таких устройств, то java в принципе не подходит). К тому же, генерация кода происходит на этапе компиляции и соответственно только она немного и замедляется
А подскажите где можно посмотреть как сделать авторизацию с помощью токена или кто-то подскажет!Спасибо! Пробовал разные варианты но пока не получается
Вам по сути нужно просто отправить сначала запрос авторизации, который получает токен и сохранить его. И в последующие запросы в хедер подставлять этот токен, обычно это название хедера ворде Bearer Token. Попробуйте вот тут посмотреть www.baeldung.com/rest-assured-authentication
Здравствуйте! Извините, а не подскажете в чем может быть причина ошибок Cannot resolve symbol 'annotation' и Cannot resolve symbol 'JsonIgnoreProperties'?
День добрый, скорее всего не хватает нужной зависимости, либо конфликт версий транзитивных зависимостей. Пробовали скачать тестовый проект, он у вас собирается? Попробуйте добавить вручную зависимость mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind/2.12.2 и включить процессор аннотаций www.jetbrains.com/help/idea/annotation-processors-support.html
Это по сути одна из реализаций принципа DRY: чтобы не повторять один и тот же код в разных тестах, мы выносим его в отдельный метод и переиспользуем уже его. Если этого не сделать, то при изменении логики, придется делать правки в куче тестов, а так только в одном степе. Но перебарщивать с этим тоже не стоит, потому что можно получить либо глубокие матрешки, либо просто большую связность. Еще тут может быть непонятна необходимость, потому что в этом тестовом проекте эти степы реально больше нигде не переиспользуются, но предполагается, что еще сотни тестов у вас например будут логиниться
@@simple_automation Простите. Я все таки не совсем понимаю. В текущей реализации, я удалил класс UserSteps, потому что для тестов из вашего проекта этот класс вообще не нужен. И исходя из вашей реализации, как будто это и не нужно вовсе, потому что мы используем сервисы.
@@simple_automation а как можно сделать без сетов как на 25:00 , но только с таким json? {"records":[{"key":"1563106","value":{"ACTION":"A"}}]} ? у меня сгенерилось 3 класса .. 1 первый тот, который я назвал с полем private List records; 2 RecordsItem с полями key and value и 3 класс value.. теперь я не могу понять как описать эти поля ((. подскажи пожалуйста
@@DmytroPolischuk тебе нужно пометить @Builder все 3 класса и собирать их отдельно начиная с самого вложенного, смотри repl.it/join/ellhekfo-ivanefimov
2:02, а чего GET возвращает404 а не 204? Раз уж по-твоему 204 это ошибка отсутствия контента. Кстати. DELETE что именно должен возвращать в теле ответа, раз уж он 200 код отдает? 12:45 вот спасибо, теперь буду знать, что модели это POJO, а не DTO или Value obj. а вообще полезно, спасибо. Разве что в прочитанной перед этим статье на хабре писал что отдельно писать Assert-ы дурно пахнет, я вот хз как лучше.
Спасибо за коммент. Я так понимаю ты хотел сказать, что 204 - это на самом деле успешный ответ, указывающий на то, что отсутствует тело ответа? Это косяк да, поправлю. По поводу DELETE - c кодом 200 часто возвращают удаленную сущность.
@@simple_automation Именно, хотя как сказал опытный знакомый - главное чтобы было задокументировано, а там что хош возвращай. Нашел статью habr.com/ru/post/421005/ вот там в "StatusCode и т.п." и далее в комментариях в ответ на "но и что-то из body" приводится что стоит пользоваться только самим RA без отдельных ассертов. Было бы интересно услышать мнение.
@@archmage7710 я в целом подозрительно отношусь к советам делать что-то "только так", все зависит от конкретной ситуации и цели. Проверки только самим RA удобно/наглядно делать, когда работаешь с RA на уровене классов тестов и тело ответов не очень большое, или мы проверяем только небольшую часть из ответа. Если в ответе пришла большая портянка, то мне кажется более удобным десериализовать в объект и уже с ним делать ассерты, например сравнивая с другим объектом. Еще проверки самим RA это не удобно, если у нас более сложная структура и работа с RA находится в отдельном слое, а классы тестов про него ничего не знают(а суть проверок хочется видеть все еще на уровне тестов, чтобы не залезая в дебри реализации, понять что проверяет тест).
Не знаю, с одной стороны нормально с другой как-то не понятно . Явно не для новичков , у меня вот это подчеркнуто красным UserPojoFull::getEmail, хотя я сделал импорт класса . Такое ощущение что автор ведет повествование как-бы для новичков а потом уже в духе "ну вы знаете " .
Спасибо за отзыв. Посмотрите в настройках IDE выбрана ли JDK и какая версия Java - лямбды появились в 8й версии. Если используете IntelliJ IDEA, то попробуйте еще сделать инвалидейт кэша. Видео как часть цикла для новичков, предполагает, что вы посмотрели так же видео про основы java, там как раз рассказывается про лямбды
а что IDE пишет? кроме зависимости assertj-core ничего не нужно, можно еще глянуть что нужный метод заимпортировался import static org.assertj.core.api.Assertions.assertThat;
14:29 ну вы сильно перестарались с ускорением...10 раз просматривать видео, чтобы понять что вы нажали... 14:48 даже на минимальной скорости вообще не воспринимается
Для градла под винду добавлял вот такие зависимости: testImplementation 'io.rest-assured:rest-assured:4.4.0' implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.10.4' compileOnly 'org.projectlombok:lombok:1.18.16' annotationProcessor 'org.projectlombok:lombok:1.18.16' testCompileOnly 'org.projectlombok:lombok:1.18.16' testAnnotationProcessor 'org.projectlombok:lombok:1.18.16' testCompile("org.assertj:assertj-core:3.11.1") Десериализация времени уже не пашет, на сервисе api порезан, новые объекты по факту не создашь в бд, там всего 12 объектов и поля CreatedAt нету, поэтому данная проверка не заработает.
Я добавил в класс CreateUserResponse аннотацию @EqualsAndHashCode(callSuper = true), потому что иначе идея ругалась вот таким ворнингом "warning: Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type"
@Simple Automation, вернулся через годик, начал перепроверять знания при подготовке к новой работе и.... 1) Начиная с 26 минуты ты пишешь методы для получения юзеров в юзер степс, но, ты не передаешь никакую спецификацию и соответственно эти методы обречены на неудачу. 2) Не совсем понятно почему при создании POJO классов ты не используешь иннер классы, используя всё тело ответа - к примеру для сингл юзера у меня получилось вот такое: @Data public class SuperSingleUser{ @JsonProperty("data") private User user; @JsonProperty("support") private Support support; public User getUser(){ return user; } public Support getSupport(){ return support; } @lombok.Data public class User{ @JsonProperty("last_name") private String lastName; @JsonProperty("id") private int id; @JsonProperty("avatar") private String avatar; @JsonProperty("first_name") private String firstName; @JsonProperty("email") private String email; } @lombok.Data public class Support{ @JsonProperty("text") private String text; @JsonProperty("url") private String url; } } В чем вижу плюсы : 1)следующий метод реально начинает отрабатывать, т.к. десерриализация срабатывает корректно. public static SuperSingleUser getUser(String id){ SuperSingleUser usersFull= given().spec(REQ_SPEC).get("/"+id).as(SuperSingleUser.class); return usersFull; } 2)Ты можешь оперировать остальными данными как тебе угодно, а можешь и не оперировать. Код по работе с юзером выглядит собственно: public void getUsers3(){ SuperSingleUser user = getUser("1"); System.out.println(user.getUser().getEmail()); } 3) Работа с сервисом GET:/ /api/users/2 не реализуется ни подходом с ".extract().body().jsonPath().getList("data",UsersFull.class)" т.к. по факту для синглЮзера там лежит не список. Ни подходом с ".extract().body().jsonPath().get("data")" т.к. на выходе там лежит линкедХэшМап, которая не кастится к типу объекта юзер. В целом повторюсь - видос огонь, и не в коем случае не гоню на подачу материала, но вот такие мини косячки убили 2 часа на разборы с проблемами. З.Ы. - поговаривают нынче ретрофит популярен - если есть скилл в нем, поставил бы лайк за обучающий видос
Иннер классы полезная штука, но это уже не влезло в видео:) И еще одна проблема, что их обычно использую только в определенных местах, в большей части проще сгенерировать автоматом большой класс и не копаться в нем.
Подскажите как пофиксить 1) Cannot deserialize object because no JSON deserializer found in classpath. Please put Jackson (Databind), Gson, Jackson, or Yasson in the classpath. 2) no suitable method found for extracting(UserPojoFu[...]Email)
Мне помогло добавление Jackson Databind в зависимости
mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind/2.13.3
Видео просто потрясающее: в рунете я просто ничего похожего не смог найти. Единственное что мне как новичку приходится данное видео пересматривать по несколько раз, т.к. концентрация полезной информации на одну секунду повествования крайне велика.
Пожалуйста, продолжайте свою деятельность. Уверен, что незаслуженно малое количество просмотров в будущем скорректируется в большую сторону.
лаконичность называется =)
+1
Лучшее бесплатное обучающие видео по автоматизации, которое я когда-либо видел, пожалуйста, не останавливайтесь в создании контента
Друг, ты действительно красавчик! Единственное - попробуй в начале, середине и конце видео напоминать смотрящим, чтоб подписывались, тогда дела пойдут сильно лучше... Народ забывает + не знает, что это важно.
Жду следующего видео! Было бы круто, если расскажешь про построение апи с нуля... А-ля имеем сервис, в нем несколько рабочих апишек и какая-нибудь небольшая интеграция, например для получения токена, который используется у нас в запросах. Интеграцию можно глушить или не глушить.. Да или просто без интеграций..
Еще идеи для видео:
- Заглушки. Как глушить, как настраивать.
- Тестовые данные в виде фабрик для сквозных тестов(happy path). Подумать над ddt, держим пул данных и генерим рандом фабрику из пула - Передача в запросы JSON-файлов.
- Паттерны для API тестирования.
Спасибо вам! наконец-то понятное видео и без воды! Не бросайте канал, пожалуйста, у вас дар объяснять. Удачи вам!
21 минуту прорабатывал около трех часов, одно из самых полезных видео в моей жизни, спасибо
Чувак, ты реально крут! Ты так просто и понятно с примерами всё объясняешь, что становится реально понятно, как это работает. Я за пару часов просмотра твоих роликов уяснил для себя больше полезной и нужной мне инфы, чем за несколько дней поиска и просмотра других авторов. Не забрасывай это дело. У тебя очень хорошо получается объяснять. Информации в Интернете много, но толково объяснить её могут единицы.
Автор заслуживает лайков, без лишней воды ! Приятно слушать и видеть вашу работу!)
Очень здорово: хорошая подача, ничего лишнего, грамотный язык, без всяких эээканий и т.д. Прям огонь!
Спасибо за простоту объяснения, грамотность и нужный материал. Отдельный плюс за голос, который прямо успокаивает и вселяет уверенность, что все просто и все получится)
Только не останавливайся. Идея для следующего видео: Создание унивеhсального фреймворка для API тестов на основе REST ASSURED
Просто супер видео, настолько сжато и доступно все разложено. Плюс еще ломбок и билдер, есть что посмотреть начинающему и не только.
Отдельное спасибо за ускоренное видео в момент написания кода
Спасибо огромное, как раз к собесу готовлюсь, а тут такой интенсив для систематизации знаний, что просто огонь!!!
Сколько полезной информации в ролике длиной в 35 минут!
Дружище, спасибо огромное! Пожалуйста, продолжай в том же духе. Успехов тебе!
Супер. Не видео, а золото.
Годный контент! Все по делу и без воды!
Лайк, подписка
Очень понравилось. Спасибо огромное, ваше объяснение лучшие, какое я видела на youtube. Жду следующего видео!
Чувак ты крут, спасибо. Сам автоматизатор, но много для себя нового и полезного узнал! Качественное видео. Подписка!
Прекрасный источник данных, все понятно и интересно рассказано. Спасибо за видео.
Кстати! еще как вариант - видео по поводу автоматической генерации pojo из сваггера, например инструмент swagger codegen
Хорошо объясняешь, ставлю жирный лайкос!
Спасибо за понятный и толковый разбор!
Оч крутой контент! Автору однозначно лайк!
Не задумывались курсы проводить или взять людей на платный менторинг? С радостью бы занял одно из мест ради таких глубоких объяснений.
Дружище, спасибо тебе огромное. Всё невероятно понятно и очень полезно!
Шикарное объяснение, спасибо
Огонь! очень круто! ждём еще
Отлично, ну прям отлично )👍
Спасибо за труд дружыще!!!
Очень познавательно и интересно сделано. Спасибо!
Спасибо большое за ваши уроки!
Спасибо большое, как раз на работе пригодилось, сэкономил моё время =)
С последних 10 минут скорость добавления нового кода сильно увеличилась, а с последних 5 минут немного жесть началась в плане изменений и скорости их имплементации :(
Но, не смотря на это - контент ТОП!
ОГОНЬ!!!🍻🍺🍺👍
Спасибо большое! как всегда очень крутое обучающее видео!
ставлю лукас, искал инфу про десериализацию теперь все стало понятно)
ОЙ как хорошо - нравица
Осилил за два дня, переписал себе весь код в нескольких классах и "этапах", которых у Вас в исходном коде не осталось
Опять же, потрясающий труд, спасибо огромное.
Я очень надеюсь суметь адаптировать полученные знания под свои автотесты.
Буду очень признателен, если подскажете:
Я сейчас работаю над автотестами (поднимаю все с нуля), которые вынужден буду запускать в чужой системе, а именно - на основе Jira( наши продукты - это надстройки на неё).
Хочу сократить издержки по времени необходимые на прогон теста, путем использования вместо методов, вызываемых через UI-интерфейс Jira, предоставляемые ими API. То есть логины, заполнение полей и так далее делать не селениумом/селенидом, а Rest запросами
Скажите, оптимально ли подобным образом комбинировать передачу информации в запросах, при написании UI-автотестов? Типа инфраструктура на API, а UI тесты - на интерфейсах. Не сильно ли это также усложняет архитектуру тестов?
Да, я сам пропагандирую такой подход: стараться делать, насколько это возможно, вспомогательные действия через api, а через ui только непосредственно проверяемые шаги. А в идеале в принципе большую часть функционала проверять именно через api, тесты чисто на ui перенести в юнит тесты, а в функциональных ui тестах оставить только небольшой смоук или проблемные места именно связанные с UI
Мда, респект тебе, автор.
Набрать 28000 просмотров на видео про Жабу - это сильно) Я теперь не удивляюсь, что автотестеры получают в месяц как я за полгода.
Блииин, какая трешатина. И синтаксис Джава ужасно ужасный. Но.... ))))
Будьте добры, помедленней! Я записую!
Не надо помедленне. Ставь на паузу! За такое короткое время столько офигенное инфы!
Спасибо, очень понятно и по делу
Автор, очень классно вещаете! ждем новых видосов)
Как же сильно я ошибся, поверив, что длительность видоса - 35 минут)
🤣🤣🤣🤣🤣
Видео топ!
Здравствуйте! Очень понравилось.
Можно подробнее о популярной структуре проекта для API тестов: steps, API helper, параметризация (DataProvider)?
Привет, добавлю в планы:) Но если есть конкретные вопросы/сложности - пишите, возможно так быстрее отвечу
@@simple_automation Спасибо за ответ. Я руками тестирую. Получил задачу потихоньку автоматизировать. Стек Java, TestNG, Rest assured.
1. Интересует каркас боевого проекта автотестов.
2. Более боевой пример @DataProvider (или что вместо него).
3. Несколько тестовых стендов: как лучше сделать path генератор, чтобы урлы стенда были в конфиги или в классе константами прописать?
@@ДамирИ-ы7ж про типично структуру тестового фреймворка и testng планируется отдельное видео. Для конфигов я обычно использую typesafe библиотеку, про это рассказывал тут ruclips.net/video/YD7sjAO0BLY/видео.html , для разделения по стендов просто выношу в корень конфига название стенда и вот так выглядит метод создания конфига в фабрике private TestConfigFactory(){}
private TestConfigFactory(){
if(config == null){
Config testConfig = ConfigFactory.systemProperties()
.withFallback(ConfigFactory.systemEnvironment())
.withFallback(ConfigFactory.parseResources("test.conf"));
String env = testConfig.getString("env");
config = testConfig.getConfig(env).withFallback(testConfig).resolve();
}
}
Очень классно, но речь очень быстрая :( Это первые видео на ютубе где приходится скорость делать на 0.75 :D
Да, форма подачи подразумевает отсутсвие длинных пауз и лишней воды, что бы каждый мог подобрать под себя скорость и не нужно было при это чего-то перематывать. Так же подразумевал, что при необходимости видео можно остановить и посмотреть нужный кусок кода или пересмотреть несколько раз.
если знаком с retrofit, раскатай плиз его для примера))
Можно еще видео по этой теме, пожалуйста? Очень нравится как ты объясняешь, но хочется больше
Может есть какие-то конкретные пожелания?
@@simple_automation побольше про аннотации и работу с junit и lombok. А еще поподробнее про objectMapper хотелось бы)
Спасибо за видео) можно будет видео про параметизированные тесты в RestAssured ?
Параметризация делается на уровне Junit(ну или TestNG), про это есть в видео ruclips.net/video/RAOAcq97KZM/видео.html
Очень круто!!!! спасибо.
Но скорость великовата хоть и джун python но осилил))
Отличная скорость! В плеере под себя регулируй! На 0,75 поставь.
Вы использовали pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ, но в formatter уже DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); Вот эта выделенная "Z" зачем? Я попробовал сделать как в паттерне, но тогда ошибка о невозможности распарсить- ошибка на 24 символе (index 23). Аналогичный результат, если убрать "Z" из десириалайзера вообще.
Можете пожалуйста пояснить?
Z означает таймзону, точнее нулевой оффсет относительно UTC. Если добавить апостроф или кавычки(зависит от парсера), то это уже будет просто буква, то-есть элемент форматирования как символы - и : например. И обратите внимание, что вокруг Z именно одинарные кавычки, как вокруг T. А есть еще какой-то текст в ошибке, стэктрейс?
@@simple_automation Текст ошибки, если в formatter убрать кавычки вокруг Z: сom.fasterxml.jackson.databind.JsonMappingException: Text '2022-12-01T22:50:21.671Z' could not be parsed at index 23 (through reference chain: pojos.CreateUserResponse["createdAt"])
java.lang.RuntimeException: com.fasterxml.jackson.databind.JsonMappingException: Text '2022-12-01T22:50:21.671Z' could not be parsed at index 23 (through reference chain: pojos.CreateUserResponse["createdAt"])
Присоединяюсь ко всему нижесказанному - поток информации зашкаливает, но это и круто. Скажите, пожалуйста, планируется ли ролик по возможности работы rest-assured с soap сервисами? спасибо
пока не планировал, но запланирую:)
@@simple_automation такой ролик нужен как воздух!)
@@simple_automation да, очень нужно по SOAP
Спасибо за видео, очень помогло. По Вашему мануалу все получилось, но у меня по моему тесту есть вот такая проблема..
мне в body надо передать такое
"headers":{"accept":"application/json","WAREHOUSE-TEST":"1"},
и вот куда бы я его не писал, и в поджо класс запроса и в сабо body теста и в спеку везде отдает одну и ту же ошибку
error": {
"message": "Validation error.",
"additional": {
"fieldName": "WAREHOUSE-TEST",
"message": "Header parameter is not passed.",
"bindings": [
Помогите плиз что я не так делаю( Если я запрос передаю весь стрингой тогда проходит все без ошибок и ответ правильный. Заранее спасибо.
Видео информативное, но так как написано, что автоматизация с нуля, ускорения не дают времени понять ничего...
придется раз 10 пересмотреть из-за перемоток
Спасибо, только не могу понять зачем в поджо классе нужны сеттеры, если и без них всё работает?
в целом это зависит от десериализатора, канонинчые фреймворки часто создают объект конструктором без аргументов и все значения устанавливают сеттерами, но бывает, что и просто конструктор со всеми аргументами подходит
Спасибо большое за столь приятное объяснение ! Еще очень хотелось бы посмотреть что-то про polling API, как избавиться от Thread.sleep в ожидании ответа от сервера. Знаю, что для этих целей используют метод org.awaitility.Awaitility, но он работает в другом потоке, и вызывает проблемы с сеансом. Может существуют более простые способы ?
Если я правильно понял и имеется ввиду ожидание конкретного ответа от сервера, то я обычно использую retry helper, что-то вроде codeshare.io/qPPdwM . Либо вместо таймаута обычно передают количество попыток. Проблемы же с сеансом можно тоже обычно решить, добавив логику повторной авторизации/рефреша токена или как у вас там сеансы создаются. Как-нибудь расскажу про это поподробнее
@@simple_automation Спасибо за ответ! Если не трудно, покажите, пожалуйста, пример вызова waitResult
(codeshare.io/qPPdwM) например для апи :
public TicketsResponse getTicketsResponse(String APP_URL, String token, Object request) {
return given().spec(REQ_SPEC)
.header("Authorization", "Bearer " + token)
.body(request)
.when()
.post(APP_URL + "api/v2/tickets")
.then().statusCode(200)
.log().body()
.extract().body().jsonPath().getObject("", TicketsResponse.class);
}
Что нужно передать в функцию, чтобы дождаться ответа 200 ?
@@annabelousova7596 вам нужен метод, который будет возвращать код ответа. Если вы это делаете для всех запросов, то лучше это сделать прямо в классе с запросами как метод обертку. Но я бы ждал скорее не код ответа, а что-то в теле ответа или что он будет не null. Допустиим, метод getTicketsResponseCode будет возвращать именно код ответа, тогда используется так waitResult(() -> getTicketsResponseCode(URL, token, request), 200, 5)
Привет
Самый полезный контент, который я видел. Спасибо большое!
Не совсем понял один момент: UsersSteps теперь не нужен? Ведь все методы были перенесены в сервисы (но сам класс UsersSteps остался).
День добрый, методы сервисов часто дальше группируются в еще более высокоуровневые степы. Например, в рест сервисе может быть 3 метода создать локацию, компанию и офис. И эти 3 метода можно объединить в один степ создать офис, если это часто делаете.
@Covac_ Спасибо за вопрос! Я тоже об этом подумала. Автор уже ответил! @simple_automation Спасибо за ответ!
Хорошая подача, спасибо=) Скажи, пожалуйста, что думаешь по поводу того, что аннотации в Java работают через рефлекцию, что в свою очередь сказывается на производительности, стоит оно того в угоду тому, что вы не хотите видеть геттеры и сеттеры?)
Спасибо:) Если это не разработка для устройств вроде умных часов или фитнес трекеров, то накладные расходы в наше время уже совсем не существенны(а если для таких устройств, то java в принципе не подходит). К тому же, генерация кода происходит на этапе компиляции и соответственно только она немного и замедляется
А подскажите где можно посмотреть как сделать авторизацию с помощью токена или кто-то подскажет!Спасибо! Пробовал разные варианты но пока не получается
Вам по сути нужно просто отправить сначала запрос авторизации, который получает токен и сохранить его. И в последующие запросы в хедер подставлять этот токен, обычно это название хедера ворде Bearer Token. Попробуйте вот тут посмотреть www.baeldung.com/rest-assured-authentication
Офигительно написанный код. Можете подсказать, как вы так находите места, где можно оптимизировать и как?
во многом это просто подход DRY и подольше помедитировать на код
@@simple_automation спасибо за ответ)
Ну что ж. Прошло почти 2 года и я стал понимать конец видео, просто смотря его))
Здравствуйте! Извините, а не подскажете в чем может быть причина ошибок Cannot resolve symbol 'annotation' и Cannot resolve symbol 'JsonIgnoreProperties'?
День добрый, скорее всего не хватает нужной зависимости, либо конфликт версий транзитивных зависимостей. Пробовали скачать тестовый проект, он у вас собирается? Попробуйте добавить вручную зависимость mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind/2.12.2 и включить процессор аннотаций www.jetbrains.com/help/idea/annotation-processors-support.html
@@simple_automation, добавила зависимость из указанной ссылки и ошибок нет. Спасибо.
А можно то же самое, только без переделываний, а сразу как положено, пожалуйста? голова кругом.
А зачем мы по итогу создавали UserSteps? По итогу, от этого класса можно полностью отказаться, код исполняется и без него.
Это по сути одна из реализаций принципа DRY: чтобы не повторять один и тот же код в разных тестах, мы выносим его в отдельный метод и переиспользуем уже его. Если этого не сделать, то при изменении логики, придется делать правки в куче тестов, а так только в одном степе. Но перебарщивать с этим тоже не стоит, потому что можно получить либо глубокие матрешки, либо просто большую связность. Еще тут может быть непонятна необходимость, потому что в этом тестовом проекте эти степы реально больше нигде не переиспользуются, но предполагается, что еще сотни тестов у вас например будут логиниться
@@simple_automation Простите. Я все таки не совсем понимаю. В текущей реализации, я удалил класс UserSteps, потому что для тестов из вашего проекта этот класс вообще не нужен. И исходя из вашей реализации, как будто это и не нужно вовсе, потому что мы используем сервисы.
Планируются ли видео по selenium или CI CD
Да, следующее видео как раз по Selenium WebDriver, в процессе записи. CI/CD тоже планирую, но немного позже
@@simple_automation а как можно сделать без сетов как на 25:00 , но только с таким json? {"records":[{"key":"1563106","value":{"ACTION":"A"}}]} ? у меня сгенерилось 3 класса .. 1 первый тот, который я назвал с полем private List records; 2 RecordsItem с полями key and value и 3 класс value..
теперь я не могу понять как описать эти поля ((. подскажи пожалуйста
@@DmytroPolischuk тебе нужно пометить @Builder все 3 класса и собирать их отдельно начиная с самого вложенного, смотри repl.it/join/ellhekfo-ivanefimov
@@simple_automation спасибо, теперь понял.. нужно было преобразовать в Array!
с 25:36 очень запутанно и непонятно что происходит и зачем это надо. builder куда легче для прочтения.
2:02, а чего GET возвращает404 а не 204? Раз уж по-твоему 204 это ошибка отсутствия контента. Кстати. DELETE что именно должен возвращать в теле ответа, раз уж он 200 код отдает?
12:45 вот спасибо, теперь буду знать, что модели это POJO, а не DTO или Value obj.
а вообще полезно, спасибо. Разве что в прочитанной перед этим статье на хабре писал что отдельно писать Assert-ы дурно пахнет, я вот хз как лучше.
Спасибо за коммент. Я так понимаю ты хотел сказать, что 204 - это на самом деле успешный ответ, указывающий на то, что отсутствует тело ответа? Это косяк да, поправлю. По поводу DELETE - c кодом 200 часто возвращают удаленную сущность.
@@simple_automation Именно, хотя как сказал опытный знакомый - главное чтобы было задокументировано, а там что хош возвращай.
Нашел статью habr.com/ru/post/421005/ вот там в "StatusCode и т.п." и далее в комментариях в ответ на "но и что-то из body" приводится что стоит пользоваться только самим RA без отдельных ассертов.
Было бы интересно услышать мнение.
@@archmage7710 я в целом подозрительно отношусь к советам делать что-то "только так", все зависит от конкретной ситуации и цели. Проверки только самим RA удобно/наглядно делать, когда работаешь с RA на уровене классов тестов и тело ответов не очень большое, или мы проверяем только небольшую часть из ответа. Если в ответе пришла большая портянка, то мне кажется более удобным десериализовать в объект и уже с ним делать ассерты, например сравнивая с другим объектом. Еще проверки самим RA это не удобно, если у нас более сложная структура и работа с RA находится в отдельном слое, а классы тестов про него ничего не знают(а суть проверок хочется видеть все еще на уровне тестов, чтобы не залезая в дебри реализации, понять что проверяет тест).
ты молодец, хороший контент, но звук мела - арррхг, убери его плиз.
имеется ввиду звук карандаша вначале?
@@simple_automation ага. не царапай пожалуйста, чуть не выключила и не пропустила хороший контент
Не знаю, с одной стороны нормально с другой как-то не понятно . Явно не для новичков , у меня вот это подчеркнуто красным UserPojoFull::getEmail, хотя я сделал импорт класса . Такое ощущение что автор ведет повествование как-бы для новичков а потом уже в духе "ну вы знаете " .
Спасибо за отзыв. Посмотрите в настройках IDE выбрана ли JDK и какая версия Java - лямбды появились в 8й версии. Если используете IntelliJ IDEA, то попробуйте еще сделать инвалидейт кэша. Видео как часть цикла для новичков, предполагает, что вы посмотрели так же видео про основы java, там как раз рассказывается про лямбды
@@simple_automation А причем тут лямбды ? У меня проблемы с assertJ, я в курсе за лямбды у меня на codefroce на java рэйтинг 1490
а что IDE пишет? кроме зависимости assertj-core ничего не нужно, можно еще глянуть что нужный метод заимпортировался import static org.assertj.core.api.Assertions.assertThat;
@@simple_automation да я разобрался там сам ошибку сделал :)) Вопрос снят )
14:29 ну вы сильно перестарались с ускорением...10 раз просматривать видео, чтобы понять что вы нажали... 14:48 даже на минимальной скорости вообще не воспринимается
Спасибо за комментарий, учту. А что на 14:48 не воспринимается?
@@simple_automation ошиблась тайм кодом 19:58
@@veronica2487 там ничего важного, лишние щелчки и открытие не тех файлов:) не заметил, а так бы вырезал
можно воспользоваться замедлением скорости в настройках видео. На 0.25x например.
Вы што творити то, совсем штоли?
ветка develop - ошибка 404
в какой момент ошибка 404?
@@simple_automation на гите выдало ошибку, сейчас норм.
Для градла под винду добавлял вот такие зависимости:
testImplementation 'io.rest-assured:rest-assured:4.4.0'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.10.4'
compileOnly 'org.projectlombok:lombok:1.18.16'
annotationProcessor 'org.projectlombok:lombok:1.18.16'
testCompileOnly 'org.projectlombok:lombok:1.18.16'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.16'
testCompile("org.assertj:assertj-core:3.11.1")
Десериализация времени уже не пашет, на сервисе api порезан, новые объекты по факту не создашь в бд, там всего 12 объектов и поля CreatedAt нету, поэтому данная проверка не заработает.
Я добавил в класс CreateUserResponse аннотацию @EqualsAndHashCode(callSuper = true), потому что иначе идея ругалась вот таким ворнингом "warning: Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type"
@Simple Automation, вернулся через годик, начал перепроверять знания при подготовке к новой работе и....
1) Начиная с 26 минуты ты пишешь методы для получения юзеров в юзер степс, но, ты не передаешь никакую спецификацию и соответственно эти методы обречены на неудачу.
2) Не совсем понятно почему при создании POJO классов ты не используешь иннер классы, используя всё тело ответа - к примеру для сингл юзера у меня получилось вот такое:
@Data
public class SuperSingleUser{
@JsonProperty("data")
private User user;
@JsonProperty("support")
private Support support;
public User getUser(){
return user;
}
public Support getSupport(){
return support;
}
@lombok.Data
public class User{
@JsonProperty("last_name")
private String lastName;
@JsonProperty("id")
private int id;
@JsonProperty("avatar")
private String avatar;
@JsonProperty("first_name")
private String firstName;
@JsonProperty("email")
private String email;
}
@lombok.Data
public class Support{
@JsonProperty("text")
private String text;
@JsonProperty("url")
private String url;
}
}
В чем вижу плюсы :
1)следующий метод реально начинает отрабатывать, т.к. десерриализация срабатывает корректно.
public static SuperSingleUser getUser(String id){
SuperSingleUser usersFull= given().spec(REQ_SPEC).get("/"+id).as(SuperSingleUser.class);
return usersFull;
}
2)Ты можешь оперировать остальными данными как тебе угодно, а можешь и не оперировать. Код по работе с юзером выглядит собственно:
public void getUsers3(){
SuperSingleUser user = getUser("1");
System.out.println(user.getUser().getEmail());
}
3) Работа с сервисом GET:/ /api/users/2 не реализуется ни подходом с ".extract().body().jsonPath().getList("data",UsersFull.class)" т.к. по факту для синглЮзера там лежит не список.
Ни подходом с ".extract().body().jsonPath().get("data")" т.к. на выходе там лежит линкедХэшМап, которая не кастится к типу объекта юзер.
В целом повторюсь - видос огонь, и не в коем случае не гоню на подачу материала, но вот такие мини косячки убили 2 часа на разборы с проблемами.
З.Ы. - поговаривают нынче ретрофит популярен - если есть скилл в нем, поставил бы лайк за обучающий видос
Иннер классы полезная штука, но это уже не влезло в видео:) И еще одна проблема, что их обычно использую только в определенных местах, в большей части проще сгенерировать автоматом большой класс и не копаться в нем.