Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Параметризованные тесты
Параметризованные тесты — это тестовые методы, которые запускаются несколько раз с разными входными данными. Это позволяет проверить один и тот же код при различных условиях без дублирования кода теста.
Назначение и преимущества
Основное назначение параметризованных тестов:
- Избежание дублирования кода: Один тест вместо множества похожих методов
- Полнота тестирования: Проверка разных edge cases и сценариев
- Читаемость: Наглядное отображение всех тестовых случаев
- Поддерживаемость: Легче добавлять новые тестовые данные
Реализация в JUnit 5
В JUnit 5 параметризованные тесты реализуются с помощью аннотаций @ParameterizedTest и различных источников данных:
1. @ValueSource
Для простых значений одного типа:
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
class CalculatorTest {
@ParameterizedTest
@ValueSource(ints = {1, 2, 3, 4, 5})
void testIsPositive(int number) {
assertTrue(number > 0);
}
}
2. @CsvSource
Для нескольких параметров через CSV:
@ParameterizedTest
@CsvSource({
"2, 2, 4",
"3, 3, 6",
"5, 0, 5",
"-1, 1, 0"
})
void testAdd(int a, int b, int expected) {
Calculator calc = new Calculator();
assertEquals(expected, calc.add(a, b));
}
3. @CsvFileSource
Для больших наборов данных из CSV файла:
@ParameterizedTest
@CsvFileSource(resources = "/test-data.csv")
void testFromFile(String input, String expected) {
assertEquals(expected, processInput(input));
}
4. @MethodSource
Для сложной логики генерации тестовых данных:
@ParameterizedTest
@MethodSource("provideTestData")
void testWithComplexData(String input, int expectedLength) {
assertEquals(expectedLength, input.length());
}
static Stream<Arguments> provideTestData() {
return Stream.of(
Arguments.of("hello", 5),
Arguments.of("world", 5),
Arguments.of("test", 4),
Arguments.of("", 0)
);
}
5. @EnumSource
Для перебора значений enum:
enum Status { ACTIVE, INACTIVE, PENDING }
@ParameterizedTest
@EnumSource(Status.class)
void testAllStatuses(Status status) {
assertNotNull(status);
}
Пример: Валидация email адресов
class EmailValidatorTest {
private EmailValidator validator = new EmailValidator();
@ParameterizedTest(name = "{0} is valid: {1}")
@CsvSource({
"user@example.com, true",
"invalid.email@, false",
"@example.com, false",
"user@domain, true",
"user+tag@example.co.uk, true"
})
void testEmailValidation(String email, boolean expected) {
assertEquals(expected, validator.isValid(email));
}
}
Параметризованные тесты в JUnit 4
До JUnit 5, для параметризации использовались @RunWith(Parameterized.class):
@RunWith(Parameterized.class)
public class ParameterizedTestJUnit4 {
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{ 2, 4 },
{ 3, 6 },
{ 5, 10 }
});
}
private int input;
private int expected;
public ParameterizedTestJUnit4(int input, int expected) {
this.input = input;
this.expected = expected;
}
@Test
public void testMultiply() {
assertEquals(expected, input * 2);
}
}
Лучшие практики
- Выбери подходящий источник данных: Для простых случаев используй @ValueSource, для сложных — @MethodSource
- Добавь подробные имена тестов: Используй параметр name в @ParameterizedTest для логирования
- Группируй связанные случаи: Организуй тестовые данные логично
- Не переусложняй: Если тест становится сложным для понимания, может быть лучше отдельные методы
- Используй edge cases: Включай граничные значения, пустые строки, null и т.д.
Сравнение с обычными тестами
// ❌ Без параметризации - код дублируется
@Test
void test2Plus2() { assertEquals(4, add(2, 2)); }
@Test
void test3Plus3() { assertEquals(6, add(3, 3)); }
@Test
void test5Plus0() { assertEquals(5, add(5, 0)); }
// ✅ С параметризацией - один метод
@ParameterizedTest
@CsvSource({"2, 2, 4", "3, 3, 6", "5, 0, 5"})
void testAdd(int a, int b, int expected) {
assertEquals(expected, add(a, b));
}
Параметризованные тесты — это мощный инструмент для создания более надёжного и поддерживаемого кода тестов, позволяющий одним методом охватить множество сценариев.