Конспект і таймкоди
0:00
Packages, MVC і resource controllers
Код API automation виноситься в package api, а існуючі UI-теси — в web. Для подальшої структури автор адаптує ідею MVC: test залишається місцем сценарію та перевірок, DTO описують data model, а controllers містять API operations.
Для кожного ресурсу створюється окремий controller, наприклад projects або auth. Дуже великий resource можна розділити на кілька controllers. Під час перейменування Java class в IntelliJ IDEA потрібно використовувати Rename refactoring (Shift+F6), щоб назви file і public class залишилися однаковими.
5:20
`BaseController` і порівняння лінійного та controller-based тесту
Спільна RestAssured configuration переноситься в abstract BaseController. Бібліотека RestAssured має бути доступною main-коду, тому dependency переводиться з test-only у implementation. Controllers успадковують base class і працюють з protected request specification.
Логін, пошук проєкту і створення suite розносяться між AuthController, ProjectController і SuiteController; controllers та DTO розкладаються в окремі packages. Для порівняння в тому самому class залишається початковий «брудний» сценарій і додається окремий MVC-варіант. Перенесення operations в окремі classes дає змогу розширювати кожен resource без розростання одного test class.
11:53
Assertions у тесті і перехід до DTO
Первинні перевірки мають бути видимими в тесті, а не захованими в controller. Тому API method повертає Response, а test явно перевіряє status code. Така структура спрощує code review і показує, що саме доводить сценарій.
Наступний крок — замінити JSON strings на data transfer objects, щоб мати Java types, autocomplete і зручне оновлення полів. Додаються Java Faker для унікальних test data і Lombok для генерації boilerplate. Для Lombok у IntelliJ IDEA потрібні plugin і ввімкнений annotation processing.
16:11
Генерація Java classes з JSON
Для створення DTO з JSON показано кілька варіантів: IntelliJ plugin RoboPOJOGenerator, online generator jsonschema2pojo і ChatGPT. У IntelliJ IDEA Aqua потрібний plugin недоступний, а online generator під час демонстрації не працює, тому невеликий request DTO генерується через ChatGPT.
Автор попереджає: LLM може надійно допомогти з малою JSON-структурою, але для великого response може пропусти fields, помилитися з types або вкладеністю. Таку модель потрібно перевіряти проти реального JSON.
20:10
POJO, Lombok builder і test data
POJO пояснюється як Plain Old Java Object: fields плюс getters, setters, equals, hashCode і toString. Lombok annotation @Data генерує цей типовий код. Request JSON переноситься в typed SuiteRequest, який можна передавати RestAssured замість raw string.
@Builder дає покрокову ініціалізацію nested DTO, а Java Faker генерує title і description, зокрема назву книги та Chuck Norris fact. Щоб не перевантажувати test конструкторами, створення request object виноситься в method generator/factory, який повертає готовий SuiteRequest.
27:06
Fluent DTO і перші response assertions
Lombok @Accessors(chain = true) дозволяє ланцюжком викликати setters, а @Data(staticConstructor = "of") — створювати object без явного new. У демонстрації це скорочує вкладену підготовку request data порівняно з розгорнутим builder.
Після створення suite тест має перевірити, що response містить згенерований title. Перший варіант зчитує його з RestAssured response через jsonPath().getString(...); для endpoint, який повертає масив suites, потрібно отримати list titles, а не один string.
32:28
AssertJ і перевірка колекцій
Для assertions підключається AssertJ Core, яку автор радить для різних data types і особливо collections. Оскільки suites endpoint повертає масив, тест перевіряє, що list actual titles містить title щойно створеного suite.
Перевірка лише title через JsonPath не масштабується на description та інші fields. Тому наступний крок — deserialization повного response в typed Java object і assertions проти його полів.
37:30
Response DTO і перша deserialization
З реального JSON response генерується SuiteResponse із nested data, attributes та relationships. RestAssured response переводиться в Java class через extract().as(...). Після цього test отримує autocomplete для getData(), attributes, id, type і title замість string paths.
Перший запуск виявляє, що response не приводиться до згенерованої моделі автоматично. Відео залишає цей невдалий прохід видимим, щоб показати реальну складність великих DTO і Jackson configuration.
45:50
Jackson Databind, `@JsonProperty` і різні response shapes
Для Jackson2 deserialization явно підключається Jackson Databind. Поля JSON на кшталт created-at, які не відповідають Java naming conventions, мають бути явно зв’язані з fields через @JsonProperty.
Виявляється ще одна контрактна різниця: create endpoint повертає один data object, а list endpoint — array таких objects. Одна й та сама field type не може безпечно представляти обидва shapes, тому моделі розділяються на single response і list response.
51:20
`ObjectMapper` configuration і послідовне виправлення DTO
Через зміни в Jackson знадоблюється явна RestAssured configuration з Jackson2MapperFactory та налаштованим ObjectMapper. Після цього deserialization послідовно виявляє unrecognized fields у неповному DTO. Помилки читаються як карта того, які fields або constructors бракують.
Автор показує, як початково можна віддати exception ChatGPT для пояснення, але не приймати відповідь без перевірки. Під час демонстрації згенерована модель пропускає кілька real response fields і змішує object з array. Це підтверджує, що великі DTO потрібно генерувати інструментом, який парсить повний JSON, і все одно звіряти з контрактом.
1:02:20
Custom RestAssured log filter і розбіжності даних
Для сталого логування request і response додається custom filter, який реалізує RestAssured OrderedFilter. Він логує request до виклику і response після нього, а також не намагається виводити порожнє body. Filter передається в base API configuration, тому всі controllers мають однакову діагностику.
Лог показує розбіжності між create і list responses: наприклад, labels в одному response мають інше значення, а description не повертається так, як очікувалося. Частина помилок належить не DTO, а неідеальному API contract.
1:09:00
RoboPOJOGenerator і межі AI-generated DTO
У повній IntelliJ IDEA демонструється RoboPOJOGenerator: у нього вставляється реальний JSON, обираються Jackson і Lombok settings, після чого plugin створює повнішу object structure. Цей результат містить поля, які пропустила LLM-generated версія.
Для маленьких JSON ChatGPT може бути зручним стартом, але для великих response автор його не радить. На кожному проєкті Jackson потребує одноразового узгодження з реальними JSON conventions. Після цього typed responses дають контрактну перевірку fields і types, а над ними можна будувати reusable assertion classes.
1:16:00
Сирий JSON для requests і typed objects для responses
Якщо request DTO поки занадто складний, request JSON можна тимчасово зберігати у resources і відправляти як file/string. Для response автор наполягає на typed object: так deserialization одразу виявляє зміну structure або field types, яка могла б поламати frontend.
Помилки Jackson потрібно читати і звіряти з документацією або пошуком, а не механічно копіювати AI-відповідь. Configuration, helpers і DTO варто рознести за окремими classes, щоб не змішувати mapping, transport і assertions.
1:20:17
Повторне використання token і controllers у `BaseTest`
Щоб не передавати token в кожен controller method, BaseController зберігає його у field і додає authorization header, якщо значення не порожнє. Token-setting method повертає controller type, щоб його можна було викликати у fluent chain. Після цього resource methods більше не мають token parameter.
Controller instances та login setup виносяться в BaseTest. Token отримується один раз у @BeforeAll, після чого ним конфігуруються ProjectController і SuiteController. Фінальний test залишає видимими лише сценарій, test data і assertions, а transport details залишаються у controllers.