지난 글에서는 기본적인 계산기 기능을 MSTest를 통해 테스트하고, TDD 사이클을 완성했습니다.
이제는 예외 처리와 경계 값 테스트, 그리고 테스트 커버리지를 높이는 고급 전략을 다뤄보겠습니다. 😎
이번 글에서는 다음 내용을 중점적으로 설명하겠습니다:
✔️ 다양한 입력 값에 대한 테스트 작성
✔️ 예외 상황에 대한 테스트 작성
✔️ 테스트 커버리지 확대 전략
✅ 테스트 커버리지(Test Coverage)란?
테스트 커버리지는 작성한 코드에서 테스트로 검증된 코드의 비율을 의미합니다.
테스트 커버리지가 높을수록 코드의 안정성이 보장됩니다.
테스트 커버리지를 높이는 방법:
- 정상 입력 값과 비정상 입력 값을 모두 테스트
- 경계 값(Boundary Value) 테스트 추가
- 예상된 예외 처리 검증
목표: 최소한 코드의 80% 이상이 테스트 커버리지에 포함되도록 설정
✅ 프로젝트 준비
이전 글에서 작성한 Calculator 클래스에 테스트 케이스를 추가하면서 진행하겠습니다.
Calculator.cs와 CalculatorTests.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편)