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

Какими фреймворками для тестирования пользуешься

2.0 Middle🔥 131 комментариев
#Тестирование

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

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

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

Фреймворки для тестирования в Java

Тестирование — неотъемлемая часть качественной разработки. За 10+ лет я работал с несколькими мощными фреймворками для автоматизации тестов в Java.

JUnit — стандарт unit-тестирования

JUnit — самый популярный и распространённый фреймворк для unit-тестов в Java. Я активно использую версию JUnit 5 (Jupiter) благодаря её современной архитектуре.

@DisplayName("Тесты для UserService")
public class UserServiceTest {
    
    private UserService userService;
    private UserRepository userRepository;
    
    @BeforeEach
    void setUp() {
        userRepository = mock(UserRepository.class);
        userService = new UserService(userRepository);
    }
    
    @Test
    @DisplayName("Должен найти пользователя по ID")
    void testFindUserById() {
        // Arrange
        User expectedUser = new User(1L, "John Doe");
        when(userRepository.findById(1L)).thenReturn(Optional.of(expectedUser));
        
        // Act
        User actualUser = userService.findById(1L);
        
        // Assert
        assertEquals(expectedUser, actualUser);
        verify(userRepository).findById(1L);
    }
    
    @ParameterizedTest
    @ValueSource(strings = {"john@example.com", "jane@example.com"})
    void testValidEmails(String email) {
        assertTrue(userService.isValidEmail(email));
    }
}

Ключевые особенности JUnit 5:

  • Аннотации: @Test, @BeforeEach, @AfterEach, @DisplayName
  • Параметризованные тесты с @ParameterizedTest
  • Гибкая модель расширений
  • Поддержка вложенных тестовых классов

Mockito — мокирование зависимостей

Mockito — незаменимый инструмент для изоляции тестируемого кода от внешних зависимостей. Я использую его практически в каждом unit-тесте.

@ExtendWith(MockitoExtension.class)
public class PaymentServiceTest {
    
    @Mock
    private PaymentGateway paymentGateway;
    
    @InjectMocks
    private PaymentService paymentService;
    
    @Test
    void testProcessPayment() {
        // Arrange
        when(paymentGateway.charge(100.0))
            .thenReturn(new PaymentResult("success", "TX123"));
        
        // Act
        PaymentResult result = paymentService.processPayment(100.0);
        
        // Assert
        assertEquals("success", result.getStatus());
        verify(paymentGateway).charge(100.0);
    }
    
    @Test
    void testPaymentFailure() {
        // Arrange
        when(paymentGateway.charge(anyDouble()))
            .thenThrow(new PaymentException("Insufficient funds"));
        
        // Act & Assert
        assertThrows(PaymentException.class, 
            () -> paymentService.processPayment(100.0));
    }
}

Основные возможности Mockito:

  • Создание mock-объектов через @Mock
  • Проверка вызовов методов через verify()
  • Настройка поведения через when().thenReturn()
  • Проверка аргументов с использованием matchers

TestNG — альтернатива JUnit

TestNG — мощная альтернатива с некоторыми дополнительными возможностями:

public class DataProviderTest {
    
    @DataProvider(name = "loginData")
    public Object[][] loginDataProvider() {
        return new Object[][] {
            {"user1", "pass1", true},
            {"user2", "pass2", true},
            {"user3", "wrongpass", false}
        };
    }
    
    @Test(dataProvider = "loginData")
    void testLogin(String username, String password, boolean expected) {
        // Test logic
    }
    
    @Test(dependsOnMethods = {"testLogin"})
    void testLogout() {
        // Зависит от успешного прохождения testLogin
    }
}

Преимущества TestNG:

  • Более гибкие data providers для параметризованных тестов
  • Зависимости между тестами
  • Встроенная параллелизация
  • Подробные HTML отчёты

AssertJ — плавные assertions

AssertJ — библиотека для написания более читаемых и выразительных проверок:

@Test
void testUserValidation() {
    User user = new User("John", 25, "john@example.com");
    
    assertThat(user)
        .isNotNull()
        .hasFieldOrPropertyWithValue("name", "John")
        .hasFieldOrPropertyWithValue("age", 25);
    
    assertThat(user.getEmails())
        .isNotEmpty()
        .contains("john@example.com")
        .hasSize(1);
}

Плюсы AssertJ:

  • Цепочка методов (fluent API)
  • Лучшие сообщения об ошибках
  • Поддержка проверок коллекций, дат, исключений

Spring Test — тестирование Spring приложений

Spring Test — специализированный фреймворк для интеграционных тестов Spring приложений:

@SpringBootTest
@ActiveProfiles("test")
public class UserControllerTest {
    
    @Autowired
    private MockMvc mockMvc;
    
    @MockBean
    private UserService userService;
    
    @Test
    void testGetUser() throws Exception {
        User user = new User(1L, "John Doe");
        when(userService.findById(1L)).thenReturn(user);
        
        mockMvc.perform(get("/users/1")
                .contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.name").value("John Doe"));
    }
}

Основной функционал:

  • MockMvc — тестирование REST контроллеров
  • @WebMvcTest — слоистое тестирование только web layer
  • Тестовые профили через @ActiveProfiles

Arquillian — интеграционное тестирование

Для сложных интеграционных сценариев с реальными контейнерами я использовал Arquillian:

@RunWith(Arquillian.class)
public class DeploymentTest {
    
    @Deployment
    public static WebArchive createDeployment() {
        return ShrinkWrap.create(WebArchive.class)
            .addClasses(UserService.class, User.class)
            .addAsResource("persistence.xml", "META-INF/persistence.xml");
    }
    
    @Test
    void testEjb() {
        // Тест в контексте приложенного архива
    }
}

Мои практики и рекомендации

Стратегия тестирования:

  • 70% unit-тестов — быстрые, изолированные, без зависимостей
  • 20% интеграционных тестов — тестирование взаимодействия компонентов
  • 10% E2E тестов — критические бизнес-сценарии

Целевое покрытие:

  • Минимум 80% code coverage для production кода
  • Все public методы должны иметь тесты
  • Обязательное покрытие граничных случаев и exception paths

Лучшие практики:

  • AAA-паттерн: Arrange → Act → Assert
  • Читаемые имена тестов, описывающие сценарий
  • Один assert на один логический вывод
  • Избегать flaky тестов (нестабильность из-за времени, порядка)
  • Использование тестовых контейнеров (Testcontainers) для real DB/Redis

Выбор фреймворка зависит от контекста проекта, но комбинация JUnit + Mockito + AssertJ — это классический и надёжный стек, который я рекомендую в большинстве случаев.

Какими фреймворками для тестирования пользуешься | PrepBro