Что такое конструкция switch-case?

Ответ

switch-case — это управляющая конструкция в Java, предназначенная для выбора одного из множества блоков кода для выполнения на основе значения выражения. Она служит более читаемой и эффективной альтернативой длинным цепочкам if-else-if, когда проверяется одно и то же выражение на равенство с различными константами.

Базовый синтаксис (до Java 14):

switch (expression) {
    case value1:
        // Код для value1
        break; // Прерывает выполнение switch
    case value2:
        // Код для value2
        break;
    default:
        // Код, если ни один case не совпал (опционально)
}

Типы выражений: В switch можно использовать byte, short, char, int, их обёртки (Byte, Short и т.д.), String (с Java 7) и enum.

Пример из практики тестирования:

public String getStatusMessage(int httpCode) {
    String message;
    switch (httpCode) {
        case 200:
            message = "OK";
            break;
        case 404:
            message = "Not Found";
            break;
        case 500:
            message = "Internal Server Error";
            break;
        default:
            message = "Unknown Status";
    }
    return message;
}

Современный синтаксис (Java 14+, switch expressions): Более компактный и безопасный (исключает ошибку забытого break).

String message = switch (httpCode) {
    case 200 -> "OK";
    case 404 -> "Not Found";
    case 500 -> "Internal Server Error";
    default -> "Unknown Status";
};
// Тест:
assertEquals("Not Found", getStatusMessage(404));

Что важно для тестировщика:

  1. Покрытие ветвей: При тестировании метода, содержащего switch, необходимо обеспечить покрытие всех значимых case-ветвей и ветки default. Это классический объект для анализа покрытия кода (branch coverage).
  2. Поиск дефектов: Частая ошибка — "проваливание" (fall-through) из-за забытого break, что приводит к выполнению кода из нескольких case. Тесты должны выявлять такое поведение.
  3. Тестирование граничных значений: Особенно для default-ветки — проверка реакции на неожиданные или недокументированные входные значения.

Ответ 18+ 🔞

Э, слушай, давай про этот ваш switch-case поговорим. Ну, типа, такая штука в Java, чтобы не городить овердохуища if-else подряд, как будто на дворе 2002-й год. Суть простая: есть у тебя какое-то выражение — число там, строка, enum — и ты смотришь, с какой из кучки констант оно совпало. Как на викторине: угадал — получаешь приз в виде выполнения своего куска кода.

Старая школа (до 14-й Java): Выглядело это примерно так, блядь:

switch (expression) {
    case value1:
        // Делаем раз
        break; // Обязательно стопануться, а то пойдём дальше!
    case value2:
        // Делаем два
        break;
    default:
        // А это если нихуя не совпало
}

Типа, взяли int, String или ещё что — и поехали сравнивать. Но тут, чувак, главная засада — этот самый break. Забудешь его поставить — и пошло проваливание (fall-through). Выполнится один case, а потом, как по конвейеру, начнёт лезть в следующий, и следующий, пока break не встретится или switch не кончится. Сплошное волнение, ёбать. Ошибка классическая, все на этом обжигались.

Пример из жизни, чтобы не быть голословным: Допустим, ты тестируешь какой-нибудь метод, который код HTTP-статуса в человеческий текст переводит.

public String getStatusMessage(int httpCode) {
    String message;
    switch (httpCode) {
        case 200:
            message = "OK";
            break;
        case 404:
            message = "Not Found";
            break;
        case 500:
            message = "Internal Server Error";
            break;
        default:
            message = "Unknown Status";
    }
    return message;
}

Вроде всё просто. Но представь, если бы я забыл break после case 404. Прилетела бы 404-я ошибка, метод сказал бы "Not Found", а потом, ёпта, спокойно так перешёл бы в case 500, перезаписал бы сообщение на "Internal Server Error" и вернул уже его. Полная пиздопроебибна! Клиент получит не то, что ожидал. Вот на такие косяки тестировщик и должен реагировать первым делом.

Новая школа (Java 14+): Тут ребята одумались и сделали switch expressions. Красота, ядрёна вошь! Теперь можно писать компактно, и про "проваливание" можно забыть, если использовать стрелочки.

String message = switch (httpCode) {
    case 200 -> "OK";
    case 404 -> "Not Found";
    case 500 -> "Internal Server Error";
    default -> "Unknown Status";
};
// Тестим:
assertEquals("Not Found", getStatusMessage(404));

Смотри, как элегантно: выбрали ветку — получили значение. Никаких лишних break, никакого риска всё сломать по забывчивости. Уже легче дышать.

А теперь, собственно, что тебе, как тестировщику, с этим всем делать?

  1. Покрытие ветвей — это святое. Твоя задача — проебаться по всем этим case и по default. Запустил код с 200, 404, 500 и каким-нибудь левым числом вроде 999, чтобы в default зайти. Если какая-то ветка осталась нетронутой — это твой косяк, чувак. Доверия к такому тесту — ноль, ёбать.
  2. Охота на "проваливание". Особенно в легаси-коде, написанном по старинке. Создавай тесты, которые проверяют не только результат для "своего" кейса, но и чтобы он не просочился в соседний. Это прям классический дефект.
  3. Граничные значения и default — твои лучшие друзья. Что будет, если передать 0? А -1? А Integer.MAX_VALUE? Всё это должно аккуратно приземлиться в default и выдать адекватный результат (ошибку, дефолтное сообщение), а не выкинуть исключение или, того хуже, молча отработать как первый case. Вот тут твоё подозрение, ёбать, чувствовать должно работать на полную.

Короче, switch-case — инструмент вроде простой, но, если в него не врубиться, можно наловить таких граблей, что потом неделю спина болеть будет. Современный синтаксис жизнь упростил, но старый код ещё везде валяется, так что будь начеку.