← Назад к вопросам

Для чего нужен Assert в тестировании?

1.0 Junior🔥 191 комментариев
#Тестирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Assert в тестировании Java

Assert (утверждение) — это инструмент для проверки корректности выполнения кода во время тестирования. Это основа всех unit тестов.

Что такое Assert?

Assert — это метод, который проверяет, что условие истинно. Если условие ложно, то тест падает (fail).

// Простой assert
assert 5 > 0;  // true — тест продолжает работу
assert 5 < 0;  // false — тест падает с AssertionError

Основные фреймворки

1. JUnit Assert (основной)

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class CalculatorTest {
    
    @Test
    public void testAddition() {
        Calculator calc = new Calculator();
        int result = calc.add(2, 3);
        
        // Проверка результата
        assertEquals(5, result);  // Ожидаемое = Актуальное
    }
    
    @Test
    public void testDivisionByZero() {
        Calculator calc = new Calculator();
        
        // Проверка выброса исключения
        assertThrows(ArithmeticException.class, () -> {
            calc.divide(5, 0);
        });
    }
}

Основные методы JUnit:

// Проверка равенства
assertEquals(expected, actual);
assertEquals(5, calculator.add(2, 3));

// Проверка идентичности (==)
assertSame(obj1, obj2);
List list = new ArrayList<>();
assertSame(list, list);

// Проверка на null
assertNull(value);
assertNotNull(value);

// Проверка булевых значений
true(condition);
assertFalse(condition);

// Проверка выброса исключения
assertThrows(ExceptionType.class, () -> {
    // Код, который должен выбросить исключение
});

// Проверка сообщения об ошибке
assertThrows(IllegalArgumentException.class, () -> {
    throw new IllegalArgumentException("Invalid input");
});

// Проверка, что код НЕ выбрасывает исключение
assertDoesNotThrow(() -> {
    // Код, который не должен выбросить исключение
});

// Группировка assert'ов
assertAll(
    () -> assertEquals(5, result),
    () -> assertNotNull(result),
    () -> assertTrue(result > 0)
);

// Сообщение об ошибке
assertEquals(5, result, "Addition failed: 2 + 3 should be 5");

// Условное выполнение
assumingThat(condition, () -> {
    assertEquals(expected, actual);
});

2. AssertJ (более читаемый синтаксис)

import static org.assertj.core.api.Assertions.*;

public class UserServiceTest {
    
    @Test
    public void testCreateUser() {
        User user = userService.createUser("John", 30);
        
        // Более читаемый синтаксис
        assertThat(user)
            .isNotNull()
            .hasFieldOrPropertyWithValue("name", "John")
            .hasFieldOrPropertyWithValue("age", 30);
        
        // Проверка коллекций
        assertThat(user.getHobbies())
            .isNotEmpty()
            .contains("Reading", "Coding")
            .hasSize(2);
        
        // Проверка строк
        assertThat(user.getName())
            .isNotBlank()
            .startsWith("J")
            .hasLength(4);
    }
    
    @Test
    public void testSoftAssertions() {
        User user = new User("Alice", 25);
        
        // Soft assertions — продолжают проверку, даже если одна провалилась
        SoftAssertions softly = new SoftAssertions();
        softly.assertThat(user.getName()).isEqualTo("Alice");
        softly.assertThat(user.getAge()).isEqualTo(25);
        softly.assertThat(user.getEmail()).isNotNull();  // Может провалиться
        softly.assertAll();  // Проверяет все вместе
    }
}

3. Hamcrest Matchers

import static org.hamcrest.Matchers.*;
import static org.hamcrest.MatcherAssert.assertThat;

public class ListTest {
    @Test
    public void testList() {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        
        // Hamcrest синтаксис
        assertThat(numbers, hasSize(5));
        assertThat(numbers, hasItems(1, 3, 5));
        assertThat(numbers, everyItem(greaterThan(0)));
        
        // Проверка строк
        assertThat("Hello", 
            allOf(
                startsWith("He"),
                containsString("ell"),
                endsWith("lo")
            )
        );
    }
}

Практические примеры

Пример 1: Проверка логики калькулятора

public class CalculatorTest {
    private Calculator calc;
    
    @BeforeEach
    public void setUp() {
        calc = new Calculator();
    }
    
    @Test
    public void testAdd() {
        // Arrange
        int a = 5;
        int b = 3;
        int expected = 8;
        
        // Act
        int actual = calc.add(a, b);
        
        // Assert
        assertEquals(expected, actual, "5 + 3 should equal 8");
    }
    
    @Test
    public void testSubtract() {
        assertEquals(2, calc.subtract(5, 3));
    }
    
    @Test
    public void testDivideByZero() {
        assertThrows(ArithmeticException.class, 
            () -> calc.divide(10, 0),
            "Division by zero should throw ArithmeticException"
        );
    }
    
    @Test
    public void testMultiply() {
        int result = calc.multiply(4, 5);
        assertAll(
            () -> assertNotNull(result),
            () -> assertEquals(20, result),
            () -> assertTrue(result > 0)
        );
    }
}

Пример 2: Проверка сервиса

public class UserServiceTest {
    
    @Test
    public void testUserCreation() {
        // Arrange
        UserService service = new UserService();
        
        // Act
        User user = service.createUser("John", "john@example.com");
        
        // Assert
        assertThat(user)
            .isNotNull()
            .hasFieldOrPropertyWithValue("name", "John")
            .hasFieldOrPropertyWithValue("email", "john@example.com");
    }
    
    @Test
    public void testUserNotFound() {
        UserService service = new UserService();
        
        assertThrows(UserNotFoundException.class, 
            () -> service.getUser(-1)
        );
    }
    
    @Test
    public void testGetAllUsers() {
        UserService service = new UserService();
        service.createUser("Alice", "alice@example.com");
        service.createUser("Bob", "bob@example.com");
        
        List<User> users = service.getAllUsers();
        
        assertThat(users)
            .isNotEmpty()
            .hasSize(2)
            .extracting(User::getName)
            .contains("Alice", "Bob");
    }
}

Пример 3: Mockito с assert

import static org.mockito.Mockito.*;

public class OrderServiceTest {
    
    @Test
    public void testOrderProcessing() {
        // Arrange
        PaymentService paymentService = mock(PaymentService.class);
        when(paymentService.processPayment(100.0)).thenReturn(true);
        
        OrderService orderService = new OrderService(paymentService);
        
        // Act
        boolean result = orderService.placeOrder(100.0);
        
        // Assert
        assertTrue(result, "Order should be placed successfully");
        verify(paymentService, times(1)).processPayment(100.0);
    }
}

Правила написания хороших assert'ов

1. One assertion per test (концепция)

// ❌ Плохо — много проверок
@Test
public void testUser() {
    User user = createUser();
    assertEquals("John", user.getName());
    assertEquals(30, user.getAge());
    assertNotNull(user.getEmail());
    assertTrue(user.isActive());
}

// ✅ Хорошо — одна проверка
@Test
public void testUserNameIsCorrect() {
    User user = createUser();
    assertEquals("John", user.getName());
}

// Или использовать assertAll для группировки
@Test
public void testUserCreation() {
    User user = createUser();
    assertAll(
        () -> assertEquals("John", user.getName()),
        () -> assertEquals(30, user.getAge()),
        () -> assertNotNull(user.getEmail())
    );
}

2. Исполку сообщения об ошибке

// ❌ Плохо — нет сообщения
assertEquals(expected, actual);

// ✅ Хорошо — ясное сообщение
assertEquals(expected, actual, "User age should be 30");

// ✅ Хорошо с AssertJ
assertThat(user.getAge())
    .as("User age validation")
    .isEqualTo(30);

3. Проверка исключений

// ❌ Плохо
try {
    method();
    fail("Should have thrown exception");
} catch (Exception e) {
    // ...
}

// ✅ Хорошо
Exception exception = assertThrows(InvalidArgumentException.class, 
    () -> method()
);
assertThat(exception.getMessage()).contains("Invalid");

Процент покрытия тестами

Good coverage: 80%+
Excellent coverage: 90%+

Но не все строки одинаково важны:
- Business logic: 90%+
- Utils: 80%+
- Getters/Setters: 0% (не критично)

Утверждения для различных сценариев

// Позитивный тест
@Test
public void testValidInput() {
    assertEquals(expected, actual);
}

// Негативный тест
@Test
public void testInvalidInput() {
    assertThrows(Exception.class, () -> method(invalidInput));
}

// Граничные случаи
@Test
public void testBoundaryValues() {
    assertEquals(0, calc.add(0, 0));
    assertEquals(Integer.MAX_VALUE, calc.add(Integer.MAX_VALUE, 0));
}

// Производительность
@Test(timeout = 1000)
public void testPerformance() {
    // Код должен выполниться за менее чем 1000ms
}

Выводы

Assert используется для:

  1. Проверки корректности кода
  2. Валидации поведения приложения
  3. Документирования ожидаемого поведения
  4. Предотвращения регрессий при изменении кода

Хорошие практики:

  • Использовать понятные сообщения об ошибках
  • Писать четкие и простые assert'ы
  • Объединять связанные проверки в assertAll()
  • Избегать излишних проверок (KISS принцип)
  • Использовать правильный фреймворк (AssertJ, Hamcrest)

Assert — основа качественного тестирования Java приложений.

Для чего нужен Assert в тестировании? | PrepBro