본문 바로가기
카테고리 없음

📝 C# MSTest로 예외 처리 및 다양한 입력 값 테스트하기 | TDD 고급 전략

by bbongz 2025. 3. 23.

 

지난 글에서는 기본적인 계산기 기능을 MSTest를 통해 테스트하고, TDD 사이클을 완성했습니다.
이제는 예외 처리경계 값 테스트, 그리고 테스트 커버리지를 높이는 고급 전략을 다뤄보겠습니다. 😎

이번 글에서는 다음 내용을 중점적으로 설명하겠습니다:
✔️ 다양한 입력 값에 대한 테스트 작성
✔️ 예외 상황에 대한 테스트 작성
✔️ 테스트 커버리지 확대 전략


테스트 커버리지(Test Coverage)란?

테스트 커버리지는 작성한 코드에서 테스트로 검증된 코드의 비율을 의미합니다.
테스트 커버리지가 높을수록 코드의 안정성이 보장됩니다.

테스트 커버리지를 높이는 방법:

  • 정상 입력 값과 비정상 입력 값을 모두 테스트
  • 경계 값(Boundary Value) 테스트 추가
  • 예상된 예외 처리 검증

목표: 최소한 코드의 80% 이상이 테스트 커버리지에 포함되도록 설정


프로젝트 준비

이전 글에서 작성한 Calculator 클래스에 테스트 케이스를 추가하면서 진행하겠습니다.
Calculator.csCalculatorTests.cs를 그대로 사용합니다.


🚀 1. 예외 처리 테스트 작성하기

0으로 나눌 경우 예외 발생 테스트

Divide 메서드는 입력 값이 0일 경우 DivideByZeroException을 발생시켜야 합니다.
이를 MSTest에서 검증해 보겠습니다.


🧪 테스트 코드 작성

[TestMethod]
[ExpectedException(typeof(DivideByZeroException))]
public void Divide_ShouldThrowException_WhenDividingByZero()
{
    // Arrange
    var calculator = new Calculator();

    // Act
    calculator.Divide(10, 0);

    // Assert → ExpectedException 속성으로 예외 발생 검증
}

테스트 설명

  • ExpectedException 속성 → 특정 예외 발생 여부 확인
  • 나눗셈에서 0으로 나눌 경우 DivideByZeroException 발생 → 테스트 성공

🧑‍💻 Divide 메서드 수정

기존 코드를 다음과 같이 수정합니다.

public int Divide(int a, int b)
{
    if (b == 0)
        throw new DivideByZeroException("Cannot divide by zero.");
    
    return a / b;
}

👉 테스트 통과예외 처리 완료


🚀 2. 경계 값 테스트 작성하기

테스트에서는 경계 값(Boundary Value) 을 다루는 것이 중요합니다.
예를 들어 덧셈의 경우 다음과 같은 입력 값이 경계 값이 될 수 있습니다:

  • 0 (최소 값)
  • 최대 정수 값 (int.MaxValue)
  • 최소 정수 값 (int.MinValue)

🧪 경계 값 테스트 코드 작성

[TestMethod]
public void Add_ShouldHandleMaxValue()
{
    // Arrange
    var calculator = new Calculator();
    int a = int.MaxValue;
    int b = 0;
    int expected = int.MaxValue;

    // Act
    int result = calculator.Add(a, b);

    // Assert
    Assert.AreEqual(expected, result);
}
[TestMethod]
public void Add_ShouldHandleMinValue()
{
    // Arrange
    var calculator = new Calculator();
    int a = int.MinValue;
    int b = 0;
    int expected = int.MinValue;

    // Act
    int result = calculator.Add(a, b);

    // Assert
    Assert.AreEqual(expected, result);
}

테스트 설명

  • int.MaxValue → 2,147,483,647 (최대 값)
  • int.MinValue → -2,147,483,648 (최소 값)
  • 정상적으로 연산이 되어야 테스트 통과

🚀 3. 음수 값 및 경계 값 테스트 작성하기

🧪 음수 값 테스트 작성

음수 값에서도 올바른 결과가 나오는지 테스트합니다.

[TestMethod]
public void Subtract_ShouldHandleNegativeValues()
{
    // Arrange
    var calculator = new Calculator();
    int a = -10;
    int b = -5;
    int expected = -5;

    // Act
    int result = calculator.Subtract(a, b);

    // Assert
    Assert.AreEqual(expected, result);
}

👉 음수 값에서도 정상 처리 확인


🧪 경계 값에서의 나눗셈 테스트

최소, 최대 값에서 나눗셈이 올바르게 동작하는지 테스트합니다.

[TestMethod]
public void Divide_ShouldHandleMaxValue()
{
    // Arrange
    var calculator = new Calculator();
    int a = int.MaxValue;
    int b = 1;
    int expected = int.MaxValue;

    // Act
    int result = calculator.Divide(a, b);

    // Assert
    Assert.AreEqual(expected, result);
}

👉 테스트 통과 시 → 문제 없음


🚀 4. 불필요한 테스트 중복 제거

테스트 코드가 많아질 경우 중복 제거가 필요합니다.
테스트 데이터 초기화를 TestInitialize로 공통 처리


🧑‍💻 TestInitialize 속성 추가

[TestClass]
public class CalculatorTests
{
    private Calculator _calculator;

    [TestInitialize]
    public void Setup()
    {
        _calculator = new Calculator();
    }

    [TestMethod]
    public void Add_ShouldReturnSumOfTwoNumbers()
    {
        int result = _calculator.Add(3, 5);
        Assert.AreEqual(8, result);
    }
}
  • TestInitialize → 테스트 실행 전 공통 값 초기화
  • 테스트 코드 간소화 → 유지 보수성 강화

리팩토링 단계

모든 테스트가 통과했으면 코드를 최적화합니다.
👉 최종 코드는 다음과 같습니다.

public class Calculator
{
    public int Add(int a, int b) => a + b;
    public int Subtract(int a, int b) => a - b;
    public int Multiply(int a, int b) => a * b;
    public int Divide(int a, int b)
    {
        if (b == 0)
            throw new DivideByZeroException("Cannot divide by zero.");
        
        return a / b;
    }
}

👉 테스트 코드 중복 제거 및 성능 최적화 완료


🎯 마무리 및 다음 단계

지금까지 다음 내용을 완성했습니다.
✔️ 다양한 입력 값 처리
✔️ 예외 처리 및 검증
✔️ 테스트 커버리지 강화

다음 글에서는 Moq를 활용한 Mock 테스트 및 DI(의존성 주입) 을 다뤄보겠습니다.

 

👉 다음 글: C# MSTest에서 Moq로 의존성 주입 처리하기 (4편)