← Java

Конспект і таймкоди

0:00

Оголошення, ініціалізація та scope змінних

Повторюваний URL спочатку виноситься в змінну типу String. Оголошення задає тип і назву, а ініціалізація присвоює значення; неініціалізовану локальну змінну Java не дозволить використати. Тест у JUnit є методом з анотацією @Test, тому локальна змінна одного test method недоступна іншому, а спільне значення потрібно підняти на рівень test class.

3:40

Поле test class і підказки IntelliJ IDEA

baseUrl переноситься в тіло класу, після чого його можуть використовувати кілька test methods. IntelliJ IDEA підсвічує помилки та зайві конструкції, пропонує quick fixes через Alt+Enter або Option+Enter і допомагає спростити ініціалізацію. Жовті підказки варто читати, але застосовувати лише після розуміння запропонованої зміни.

8:34

Extract Method замість дублювання та коментарів

Повторювані кроки авторизації виносяться в loginUser(), а коментарі на кшталт «search for project» замінюються методами з відповідними назвами. IntelliJ IDEA може виконати Extract Method автоматично та дозволяє перейти від виклику до реалізації через Command+B або Command+Click. У результаті test method читається як послідовність кроків manual test case: open, login, search, select і wait until loaded.

16:33

Аргументи методів і спільні test data

Якщо крок потребує email і password, їх передають у loginUser як аргументи типу String. IDE показує помилку, коли method signature ще не приймає передані значення; незрозумілий текст помилки можна розібрати окремо, не передаючи секретні дані. Повторювані credentials тимчасово піднімаються в поля класу, а приклад із лапками демонструє, що вміст String та екранування треба перевіряти за фактичним значенням.

24:00

Параметризація project actions

Назву Manufacture Lite зберігають як targetProjectName і передають у search, select та wait methods. Якщо аргумент додано лише у виклик, IntelliJ IDEA може додати відповідний parameter до method signature, але всередині методу потрібно замінити старий hardcoded literal на цей parameter. Після кожного такого кроку тест запускається знову, щоб одразу помітити пропущену заміну.

29:23

Debug mode, selectors і реальна готовність сторінки

Замість довгого sleep тест запускається в debug mode з breakpoint, щоб дослідити DOM у потрібному стані. Автор перевіряє h2, link з текстом Read Me та вкладені елементи, уточнюючи selector до єдиного збігу. Важливе спостереження: контент або DOM-елемент може з’явитися раніше, ніж зміна стане помітною користувачу, тому умова завантаження має відповідати потрібному business state, а не випадковому швидкому елементу.

35:49

Credentials і URL у `.env`

Логін, password і внутрішній base URL не слід публікувати в repository. Для Java-проєкту додається Dotenv dependency через Maven Central і Gradle, створюється .env у корені, а сам файл додається до .gitignore. Значення завантажуються через Dotenv API під час запуску; IDE plugin лише полегшує підказки ключів або маскування значень і може вимагати restart.

44:07

Спільне завантаження конфігурації в `BaseTest`

Службове завантаження .env переноситься з конкретного test class у BaseTest, а тест успадковує доступ до спільної конфігурації через extends BaseTest. Rename refactoring використовується для коротшої зрозумілої назви поля без ручного виправлення всіх посилань. Це невелике спільне місце для setup, а не побудова повної test architecture наперед.

45:39

Фільтрація результатів і перевірка розміру collection

Новий сценарій шукає project без test cases і перевіряє текст Zero tests. Однієї перевірки тексту недостатньо: вона може пройти до завершення фільтрації, тому через Selenide знаходять collection видимих list items і очікують size(1). $ повертає один елемент, а $$ — collection, до якої можна застосовувати collection conditions.

53:13

Числа з UI та `parseInt`

Лічильники на сторінці спочатку отримуються як String. Regex замінює всі нецифрові символи на порожній рядок, після чого Integer.parseInt перетворює результат на число для numeric assertion. Автор показує різницю між точним очікуваним текстом і перевіркою порогу: друга потребує окремого числового перетворення та зрозумілого failure message.

1:01:08

Динамічні й одноразові assertions

Selenide condition на кшталт shouldHave(text(...)) очікує потрібний стан протягом певного часу, тоді як getText() плюс JUnit assertion читає значення лише один раз. Якщо frontend спочатку показує 0, а потім 102, одноразове читання може зробити тест flaky. Перед статичною числовою перевіркою слід хоча б дочекатися видимості або іншої надійної precondition; повторюваний parsing виноситься в один method.

1:06:48

Параметризований selector і повторне використання element

Selector з назвою project формується через String.format, де %s замінюється на targetProjectName. Після фільтрації видимих items тест спочатку підтверджує, що знайдено рівно один результат, потім бере цей element і шукає потрібний дочірній p відносно нього. Це прибирає повторний глобальний пошук і зберігає зв’язок assertion з уже перевіреним project item.

1:11:37

Intent-level methods для assertions

Низькорівневі selector, collection і parsing operations виносяться в methods на кшталт countOfProjectsShouldBeEqualTo, countOfTestCasesShouldBeEqualTo та перевірку total count. Test method після цього показує намір сценарію й очікувані числа, а не деталі DOM. Параметри expectedSize або expectedCount дають використовувати ті самі перевірки з різними даними.

1:16:24

Text conditions і читання бібліотеки

Selenide має різні text conditions: partial, exact, case-sensitive та варіанти, що враховують або ігнорують вкладені elements і whitespace. Їх слід вибирати за потрібним контрактом, а не звичкою. Через автодоповнення, перехід до реалізації та Project view можна дослідити доступні classes і methods бібліотеки; налаштування Always Select Opened File полегшує навігацію по її структурі.

1:21:00

Спільні parsers для `int` і `double`

Універсальний parseIntegerFromString переноситься до окремого utilities package як public static method і підключається static import. Поруч створюється parser для double, щоб обробляти UI-значення на кшталт coverage з десятковою частиною. Відео також пояснює різницю між primitive int і reference type Integer, статичними methods та methods, які повертають значення замість void.

1:27:16

Організація test class, `boolean` і практика

Рекомендований порядок у класі: test data, самі tests, а потім допоміжні methods. Спершу можна залишати methods біля конкретного test class, побачити реальне дублювання й лише тоді ділити UI на Page Objects або components. Boolean.parseBoolean і assertEquals(expected, actual) показані як ще один приклад перетворення тексту з UI; практична задача — написати три-чотири читабельні tests, винести secrets у .env і потренувати IDE refactorings.

1:31:32

Commit review, Gradle і JUnit lifecycle

Перед commit потрібно переглянути кожен changed line і переконатися, що .env не потрапив до repository. Gradle configuration коригується так, щоб tests можна було запускати з command line через gradle test, а не лише кнопкою IDE. @BeforeAll виконує спільний open/login один раз перед усіма tests, @BeforeEach може перевідкривати home page перед кожним test; наприкінці автор пропонує так само дослідити відповідні after hooks.