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

Что такое положительный тест-кейс?

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

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

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

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

# Положительный тест-кейс (Happy Path Test)

Положительный тест-кейс — это тест, который проверяет, работает ли функционал корректно при нормальных, ожидаемых условиях и с валидными входными данными. Это основной сценарий использования, когда всё идёт по плану.

Определение

Положительный тест-кейс:

  • Использует валидные и корректные данные
  • Проверяет ожидаемое поведение системы
  • Тестирует успешный путь выполнения (happy path)
  • Должен завершиться успехом
  • Проверяет, что система работает как ожидается в нормальных условиях

Противоположность: Отрицательный тест-кейс

Отрицательный тест-кейс проверяет поведение при:

  • Невалидных данных
  • Граничных условиях
  • Исключительных ситуациях
  • Ошибочных сценариях

Пример: Сервис регистрации пользователя

public class UserService {
    private final UserRepository userRepository;
    
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    public User registerUser(String email, String password, String fullName) 
            throws UserAlreadyExistsException, InvalidEmailException {
        
        // Валидация email
        if (!isValidEmail(email)) {
            throw new InvalidEmailException("Invalid email format");
        }
        
        // Проверка, что пользователь не существует
        if (userRepository.existsByEmail(email)) {
            throw new UserAlreadyExistsException("User with this email already exists");
        }
        
        // Хеширование пароля
        String hashedPassword = hashPassword(password);
        
        // Создание пользователя
        User user = new User();
        user.setEmail(email);
        user.setPassword(hashedPassword);
        user.setFullName(fullName);
        user.setCreatedAt(new Date());
        user.setActive(true);
        
        // Сохранение в БД
        return userRepository.save(user);
    }
    
    private boolean isValidEmail(String email) {
        return email != null && email.matches("^[A-Za-z0-9+_.-]+@(.+)$");
    }
    
    private String hashPassword(String password) {
        return BCrypt.hashpw(password, BCrypt.gensalt());
    }
}

ПОЛОЖИТЕЛЬНЫЕ тест-кейсы

public class UserServiceTest {
    
    private UserService userService;
    private UserRepository userRepository;
    
    @Before
    public void setUp() {
        userRepository = mock(UserRepository.class);
        userService = new UserService(userRepository);
    }
    
    // ПОЛОЖИТЕЛЬНЫЙ ТЕСТ 1: Успешная регистрация
    @Test
    public void testRegisterUser_Success() throws Exception {
        // Arrange — подготовка данных
        String email = "john@example.com";
        String password = "securePassword123";
        String fullName = "John Doe";
        
        when(userRepository.existsByEmail(email)).thenReturn(false);
        when(userRepository.save(any(User.class))).thenAnswer(invocation -> {
            User user = invocation.getArgument(0);
            user.setId(1L);
            return user;
        });
        
        // Act — выполнение операции
        User result = userService.registerUser(email, password, fullName);
        
        // Assert — проверка результата
        assertNotNull(result);
        assertEquals(email, result.getEmail());
        assertEquals(fullName, result.getFullName());
        assertTrue(result.isActive());
        assertNotNull(result.getCreatedAt());
        
        // Проверяем, что save был вызван ровно один раз
        verify(userRepository, times(1)).save(any(User.class));
    }
    
    // ПОЛОЖИТЕЛЬНЫЙ ТЕСТ 2: Успешная регистрация с разными валидными данными
    @Test
    public void testRegisterUser_SuccessWithValidData() throws Exception {
        // Arrange
        String email = "jane.smith+tag@company.co.uk";
        String password = "ComplexPassword!@#123";
        String fullName = "Jane Smith";
        
        when(userRepository.existsByEmail(email)).thenReturn(false);
        when(userRepository.save(any(User.class))).thenAnswer(invocation -> {
            User user = invocation.getArgument(0);
            user.setId(2L);
            return user;
        });
        
        // Act
        User result = userService.registerUser(email, password, fullName);
        
        // Assert
        assertNotNull(result);
        assertEquals(email, result.getEmail());
        assertEquals(fullName, result.getFullName());
        assertFalse(result.getPassword().equals(password)); // пароль захеширован
        assertTrue(result.isActive());
    }
    
    // ПОЛОЖИТЕЛЬНЫЙ ТЕСТ 3: Проверка хеширования пароля
    @Test
    public void testRegisterUser_PasswordIsHashed() throws Exception {
        // Arrange
        String email = "user@example.com";
        String password = "plainPassword";
        String fullName = "Test User";
        
        when(userRepository.existsByEmail(email)).thenReturn(false);
        when(userRepository.save(any(User.class))).thenAnswer(invocation -> {
            User user = invocation.getArgument(0);
            user.setId(3L);
            return user;
        });
        
        // Act
        User result = userService.registerUser(email, password, fullName);
        
        // Assert
        assertNotNull(result.getPassword());
        assertNotEquals(password, result.getPassword());
        // Пароль должен быть захеширован, поэтому не совпадает с исходным
    }
}

ОТРИЦАТЕЛЬНЫЕ тест-кейсы (для сравнения)

public class UserServiceNegativeTest {
    
    private UserService userService;
    private UserRepository userRepository;
    
    @Before
    public void setUp() {
        userRepository = mock(UserRepository.class);
        userService = new UserService(userRepository);
    }
    
    // ОТРИЦАТЕЛЬНЫЙ ТЕСТ 1: Невалидный email
    @Test
    public void testRegisterUser_InvalidEmail() {
        // Arrange
        String invalidEmail = "invalid-email";
        String password = "password123";
        String fullName = "User";
        
        // Act & Assert
        assertThrows(InvalidEmailException.class, () -> 
            userService.registerUser(invalidEmail, password, fullName)
        );
    }
    
    // ОТРИЦАТЕЛЬНЫЙ ТЕСТ 2: Email уже существует
    @Test
    public void testRegisterUser_EmailAlreadyExists() {
        // Arrange
        String email = "existing@example.com";
        String password = "password123";
        String fullName = "User";
        
        when(userRepository.existsByEmail(email)).thenReturn(true);
        
        // Act & Assert
        assertThrows(UserAlreadyExistsException.class, () ->
            userService.registerUser(email, password, fullName)
        );
    }
    
    // ОТРИЦАТЕЛЬНЫЙ ТЕСТ 3: Null email
    @Test
    public void testRegisterUser_NullEmail() {
        // Act & Assert
        assertThrows(InvalidEmailException.class, () ->
            userService.registerUser(null, "password", "User")
        );
    }
}

Сравнение

АспектПоложительный тестОтрицательный тест
Входные данныеВалидныеНевалидные
Ожидаемый результатУспехОшибка/Exception
ЦельПроверить успешный путьПроверить обработку ошибок
СценарийНормальное использованиеГраничные/исключительные случаи
ПримерыСоздание пользователя с корректными даннымиEmail с недопустимым форматом

Типология тестов

// Положительные тесты (должны проходить)
@Test public void registerUser_ValidEmail_Success() { }
@Test public void registerUser_ValidPassword_Success() { }
@Test public void registerUser_ValidFullName_Success() { }

// Отрицательные тесты (должны выбросить исключение)
@Test public void registerUser_InvalidEmail_ThrowsException() { }
@Test public void registerUser_EmptyPassword_ThrowsException() { }
@Test public void registerUser_DuplicateEmail_ThrowsException() { }

// Граничные тесты
@Test public void registerUser_VeryLongEmail_Success() { }
@Test public void registerUser_MinimalValidPassword_Success() { }

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

✓ Начинай с положительных тестов — это базис ✓ Используй реалистичные валидные данные ✓ Проверяй все аспекты успешного выполнения ✓ Убедись, что положительные тесты проходят перед написанием отрицательных ✓ Используй выразительные имена тестов ✓ Группируй положительные и отрицательные тесты отдельно ✓ Примерное соотношение: 60% положительных, 40% отрицательных

Важность положительных тестов

Положительные тесты критичны, потому что:

  1. Они проверяют основной функционал
  2. Подтверждают, что система работает в нормальных условиях
  3. Являются базисом для регрессионного тестирования
  4. Легче писать и понимать
  5. Обеспечивают высокий уровень доверия к системе
Что такое положительный тест-кейс? | PrepBro