QA Interview Hub · База знань · Тести

Java: основи

Мова для тестів

Типи, String і різниця між == та equals

У Java два види типів: примітиви (int, long, double, boolean) і посилальні (класи, масиви, String, обгортки Integer, Boolean). Примітив зберігає значення, посилання — адресу об’єкта, тому воно може бути null.

== проти equals. Для примітивів == порівнює значення. Для об’єктів == порівнює посилання (чи це той самий об’єкт), а equals — вміст, якщо клас його перевизначив.

String a = "qa";
String b = new String("qa");
a == b;        // false: різні об’єкти
a.equals(b);   // true: однаковий текст

Літерали рядків потрапляють у пул, тому "qa" == "qa" завжди true, але рядки, створені під час виконання (з відповіді API, конкатенацією змінних, через new String), — окремі об’єкти, тож на == покладатися не можна. У тестах рядки завжди порівнюють через equals (або через assert-бібліотеку), а для можливого null — через Objects.equals(a, b).

Пастки для автоматизатора:

  • Обгортки: Integer зі значеннями −128…127 кешуються, тому == «працює» для малих чисел і ламається для великих. Порівнюйте через equals або розпакуйте в int.
  • Розпакування null у примітив кидає NullPointerException: int id = response.getId();, якщо поле — Integer зі значенням null.
  • Гроші й точні дробові значення — BigDecimal із рядкового конструктора (new BigDecimal("0.10")). double дає 0.1 + 0.2 != 0.3. Порівнюйте через compareTo: equals вважає 2.0 і 2.00 різними.

Сучасна Java для тестів: var, enum, record, текстові блоки

Поточна LTS-версія Java — 25 (раніше 21, 17, 11). Нові проєкти автоматизації варто починати на LTS і користуватися можливостями, які прибирають шаблонний код.

  • enum — фіксований набір значень: браузери, оточення, ролі. Помилку в назві видно під час компіляції, а switch по enum виразно перелічує варіанти.
    enum Browser { CHROME, FIREFOX, EDGE }
    Browser b = Browser.valueOf(System.getProperty("browser", "chrome").toUpperCase());
    valueOf кидає IllegalArgumentException для невідомого імені — це швидка й зрозуміла відмова на старті, а не дивна поведінка посеред прогону.
  • record (Java 16) — незмінний носій даних: компілятор додає конструктор, акцесори email(), equals, hashCode, toString.
    record Credentials(String email, String password) {}
    Зручно для тестових даних і параметрів. Record не можна успадкувати й не можна змінити після створення; Jackson (2.12+) вміє читати й писати records.
  • var (Java 10) — виведення типу локальної змінної: var users = new ArrayList<User>();. Тип лишається статичним; var не для полів і параметрів. Не зловживайте, коли тип неочевидний із правої частини.
  • Текстові блоки (Java 15) — багаторядкові рядки в потрійних лапках, зручні для JSON-тіл і SQL:
    String body = """
        {"email": "a@example.com", "role": "admin"}
        """;
  • Pattern matching для instanceof (o instanceof User u) і switch-вирази скорочують перевірки типів.

Усе це лише синтаксис: на швидкість тестів не впливає, але робить код тестових даних коротшим і безпечнішим.