4.3.단위 테스트 및 통합 테스트

단위 테스트와 통합 테스트는 소프트웨어 개발 과정에서 중요한 역할을 하는 테스트 방법입니다. 이들은 소프트웨어의 다양한 부분이 올바르게 작동하는지 확인하고, 버그를 조기에 발견하여 수정할 수 있도록 도와줍니다.

단위 테스트(Unit Testing)

개념

  • 소프트웨어의 가장 작은 단위(함수, 메소드)를 독립적으로 검증하는 테스트 방법입니다.

목적

  • 코드의 정확성을 검증하고, 변경으로 인한 부작용을 조기에 발견합니다.
  • 소프트웨어 설계의 품질을 향상시키고, 리팩토링을 용이하게 합니다.

특징

  • 빠른 피드백 제공
  • 자동화 가능
  • 개발 초기 단계부터 진행

도구

  • JUnit(Java), NUnit(.NET), pytest(Python) 등 언어 별 특화 도구

예시 1: 이메일 유효성 검사 함수

목적

사용자가 입력한 이메일 주소가 유효한 형식을 가지고 있는지 확인합니다.

구현 코드 예시 (EmailValidator.java)

public class EmailValidator {

    public boolean isValidEmail(String email) {
        return email != null && email.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$");
    }
}

단위 테스트 코드 예시 (EmailValidatorTest.java)

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Test;

public class EmailValidatorTest {

    private EmailValidator emailValidator = new EmailValidator();

    @Test
    public void whenValidEmail_thenTrue() {
        assertTrue(emailValidator.isValidEmail("user@example.com"));
    }

    @Test
    public void whenInvalidEmailWithoutAtSign_thenFalse() {
        assertFalse(emailValidator.isValidEmail("userexample.com"));
    }
}

테스트 케이스

  • 유효한 이메일 주소 입력 시 true 반환: "user@example.com"와 같이 유효한 이메일 형식을 입력했을 때, isValidEmail 메서드는 true를 반환해야 합니다.
  • 유효하지 않은 이메일 주소(예: ‘@' 기호 없음) 입력 시 false 반환: "userexample.com"와 같이 ‘@' 기호가 없는 이메일 형식을 입력했을 때, isValidEmail 메서드는 false를 반환해야 합니다.

이 예시는 Java와 JUnit을 사용하여 이메일 유효성 검사 로직을 단위 테스트하는 방법을 보여줍니다. 이러한 테스트는 소프트웨어 개발 과정에서 품질을 보장하고, 잠재적인 에러를 사전에 방지하는 데 도움을 줍니다.

통합 테스트(Integration Testing)

개념

  • 단위 테스트를 통과한 컴포넌트나 시스템의 부분들을 결합하여, 그들이 함께 올바르게 작동하는지 검증하는 테스트 방법입니다.

목적

  • 모듈 간 인터페이스와 상호작용의 정확성을 확인합니다.
  • 시스템의 통합 부분에서 발생할 수 있는 문제를 발견합니다.

특징

  • 모듈 간의 데이터 전달과 같은 인터페이스를 중점적으로 검사
  • 단위 테스트 이후, 시스템 테스트 전에 수행

도구

  • Postman(API 통합 테스트), Selenium(웹 애플리케이션), TestNG(다양한 통합 테스트 시나리오) 등

예시 1: 사용자 등록 API 통합 테스트

목적

사용자가 제공한 이메일 주소와 비밀번호를 통해 새로운 사용자를 등록하는 API의 정상 작동 여부를 확인합니다.

구현 코드 예시 (UserController.java)

@RestController
@RequestMapping("/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping("/register")
    public ResponseEntity<String> registerUser(@RequestBody UserDto userDto) {
        boolean result = userService.registerUser(userDto);
        if (result) {
            return ResponseEntity.ok("User registered successfully");
        } else {
            return ResponseEntity.badRequest().body("Registration failed");
        }
    }
}

통합 테스트 코드 예시 (UserControllerIntegrationTest.java)

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class UserControllerIntegrationTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void whenValidUser_thenRegisterSuccessfully() throws Exception {
        String userJson = "{\"email\":\"test@example.com\",\"password\":\"password\"}";

        mockMvc.perform(post("/users/register")
                .contentType(MediaType.APPLICATION_JSON)
                .content(userJson))
                .andExpect(status().isOk())
                .andExpect(content().string(containsString("User registered successfully")));
    }

    @Test
    public void whenInvalidUser_thenRegistrationFailed() throws Exception {
        String userJson = "{\"email\":\"\",\"password\":\"\"}";

        mockMvc.perform(post("/users/register")
                .contentType(MediaType.APPLICATION_JSON)
                .content(userJson))
                .andExpect(status().isBadRequest())
                .andExpect(content().string(containsString("Registration failed")));
    }
}

테스트 케이스

  • 유효한 사용자 정보 입력 시 등록 성공: 유효한 이메일 주소와 비밀번호를 포함하는 사용자 정보를 입력했을 때, API는 "User registered successfully" 메시지와 함께 200 OK 응답을 반환해야 합니다.
  • 유효하지 않은 사용자 정보 입력 시 등록 실패: 빈 이메일 주소와 비밀번호를 포함하는 사용자 정보를 입력했을 때, API는 "Registration failed" 메시지와 함께 400 Bad Request 응답을 반환해야 합니다.

이 예시에서는 Spring Boot의 MockMvc를 사용하여 API 엔드포인트에 대한 HTTP 요청을 시뮬레이션하고, 응답 상태 코드와 본문을 검증하는 방법을 보여줍니다. 통합 테스트는 API가 전체 시스템 내에서 예상대로 작동하는지 확인하는 데 중요한 역할을 합니다.

테스트 전략

테스트 계획

  • 테스트 범위와 목적을 명확히 합니다.
  • 필요한 리소스와 일정을 계획합니다.

테스트 설계

  • 테스트 케이스를 설계하여, 모든 요구 사항이 충족되는지 확인합니다.
  • 가정, 입력 데이터, 예상 결과를 명확히 합니다.

테스트 실행

  • 설계된 테스트 케이스를 실행합니다.
  • 발견된 결함을 기록하고, 필요한 경우 재테스트를 계획합니다.

테스트 결과 평가

  • 테스트 결과를 분석하여, 소프트웨어의 품질 수준을 평가합니다.
  • 테스트 보고서를 작성하여, 테스트 과정과 결과를 문서화합니다.

단위 테스트와 통합 테스트는 서로 보완적인 관계에 있으며, 소프트웨어 개발 과정에서 품질 관리와 버그 예방에 중요한 역할을 합니다. 이 두 테스트 방법을 적절히 활용함으로써, 더 높은 품질의 소프트웨어 개발을 달성할 수 있습니다.

source: DevOps/4.Code_Quality_Management/4.3.md