C# 개발자를 위한 단위 테스트 가이드

용과젤리·2025년 1월 17일

1. 단위 테스트란?

단위 테스트(Unit Test)는 프로그램의 개별 모듈(함수, 메서드, 클래스 등)이 의도한 대로 동작하는지 검증하는 테스트입니다. 주로 개발 초기 단계에서 작성하여, 코드 변경 시 오류를 빠르게 발견하고 유지보수를 쉽게 만들어 줍니다.

단위 테스트의 장점

  • 버그 조기 발견: 개발 단계에서 오류를 빠르게 찾아 수정할 수 있습니다.
  • 코드 품질 향상: 명확하고 견고한 코드를 작성하도록 유도합니다.
  • 리팩토링 안전성 확보: 리팩토링 후에도 기존 기능이 정상 동작하는지 검증할 수 있습니다.
  • 자동화 가능: 지속적 통합(CI) 및 배포(CD) 환경에서 자동으로 실행할 수 있습니다.

2. 단위 테스트 도구 소개

C# 개발 환경에서는 다양한 테스트 프레임워크를 사용할 수 있습니다. 대표적으로 MSTest, xUnit, NUnit이 있으며, 이 중 NUnit은 강력한 기능과 유연한 구성을 지원해 많은 개발자들이 선호합니다.

주요 단위 테스트 프레임워크 비교

프레임워크특징설치 방법
MSTestMicrosoft 공식 지원기본 제공
xUnit최신 .NET과 잘 통합됨NuGet 설치
NUnit다양한 기능과 유연한 구조NuGet 설치

3. 단위 테스트 사용 방법

  1. 테스트 프로젝트 생성: 기존 프로젝트와 분리된 테스트 프로젝트를 생성합니다.
  2. 테스트 프레임워크 설치: NuGet 패키지를 통해 NUnit 및 관련 도구를 설치합니다.
  3. 테스트 코드 작성: AAA 패턴(Arrange, Act, Assert)을 기반으로 테스트 코드를 작성합니다.
  4. 테스트 실행 및 결과 확인: Visual Studio나 CLI 도구를 통해 테스트를 실행하고 결과를 확인합니다.

4. NUnit 3와 JustMock 설명

NUnit 3

NUnit은 C# 개발에서 널리 사용되는 단위 테스트 프레임워크입니다. 간결한 문법과 풍부한 어트리뷰트를 제공하여, 효율적인 테스트 코드를 작성할 수 있습니다.

주요 특징:

  • 다양한 어트리뷰트 제공 ([Test], [TestCase], [SetUp] 등)
  • 간단하고 명확한 문법
  • 유연한 테스트 데이터 주입

JustMock

JustMock은 Telerik에서 제공하는 Mocking Framework로, 의존성이 있는 객체나 외부 리소스를 Mock 처리하여 독립적인 테스트를 가능하게 합니다.

주요 특징:

  • 인터페이스, 클래스, 메서드 Mock 지원
  • 비공개(private) 멤버 Mocking 가능 (프리미엄 버전)
  • 간결한 문법으로 빠른 테스트 작성

5. 상세 예제

Calculator 클래스

public class Calculator
{
    public int Add(int a, int b) => a + b;
    public int Divide(int a, int b)
    {
        if (b == 0) throw new DivideByZeroException("0으로 나눌 수 없습니다.");
        return a / b;
    }
}

NUnit 단위 테스트

using NUnit.Framework;

[TestFixture]
public class CalculatorTests
{
    private Calculator calculator;

    [SetUp]
    public void Setup()
    {
        calculator = new Calculator();
    }

    [Test]
    public void Add_TwoNumbers_ReturnsSum()
    {
        var result = calculator.Add(2, 3);
        Assert.AreEqual(5, result);
    }

    [Test]
    public void Divide_ByZero_ThrowsException()
    {
        Assert.Throws<DivideByZeroException>(() => calculator.Divide(10, 0));
    }
}

JustMock 예제

using Telerik.JustMock;
using NUnit.Framework;

public interface IDataService
{
    string GetData();
}

public class DataProcessor
{
    private readonly IDataService _dataService;

    public DataProcessor(IDataService dataService)
    {
        _dataService = dataService;
    }

    public string ProcessData()
    {
        return _dataService.GetData().ToUpper();
    }
}

[TestFixture]
public class DataProcessorTests
{
    [Test]
    public void ProcessData_ReturnsUpperCaseData()
    {
        var mockService = Mock.Create<IDataService>();
        Mock.Arrange(() => mockService.GetData()).Returns("test data");

        var processor = new DataProcessor(mockService);
        var result = processor.ProcessData();

        Assert.AreEqual("TEST DATA", result);
    }
}

6. NUnit 어트리뷰트 및 고급 기능

  1. [TestFixture]: 테스트 클래스 지정

    • 테스트 클래스임을 나타내며, NUnit이 테스트 클래스를 인식하게 합니다.
  2. [Test]: 테스트 메서드 지정

    • 개별 테스트 메서드를 지정합니다.
  3. [TestCase]: 다양한 입력값으로 테스트

    • 테스트 메서드에 다양한 입력값을 직접 지정할 수 있습니다.

    예제:

    [TestCase(1, 2, 3)]
    [TestCase(-1, -1, -2)]
    [TestCase(0, 0, 0)]
    public void Add_TestCases_ReturnsExpectedResult(int a, int b, int expected)
    {
        var result = calculator.Add(a, b);
        Assert.AreEqual(expected, result);
    }
  4. [TestCaseSource]: 외부 데이터 소스를 활용한 테스트

    • 배열, 컬렉션 등의 외부 데이터를 통해 다양한 테스트 케이스를 제공합니다.

    예제:

    private static object[] DivideTestCases =
    {
        new object[] { 10, 2, 5 },
        new object[] { 9, 3, 3 },
        new object[] { 15, 5, 3 }
    };
    
    [TestCaseSource(nameof(DivideTestCases))]
    public void Divide_WithTestCaseSource_ReturnsExpectedResult(int a, int b, int expected)
    {
        var result = calculator.Divide(a, b);
        Assert.AreEqual(expected, result);
    }
  5. [SetUp]: 테스트 실행 전 초기화

    • 각 테스트 실행 전 초기화 작업을 수행합니다.
  6. [TearDown]: 테스트 실행 후 정리

    • 각 테스트 실행 후 리소스를 정리합니다.
  7. [Ignore]: 테스트 제외

    • 특정 테스트를 일시적으로 실행하지 않도록 설정합니다.
  8. [Category]: 테스트 분류

    • 테스트 그룹을 지정하여 선택적 실행이 가능하도록 합니다.

7. 테스트 실행 방법

Visual Studio에서 실행

  • 메뉴: 테스트 > 테스트 탐색기
  • 단축키: Ctrl + R, A

CLI에서 실행

dotnet test

8. 단위 테스트 작성 팁

  1. 작고 명확하게 작성: 한 테스트는 한 가지 기능만 검증합니다.
  2. AAA 패턴 유지: Arrange, Act, Assert 순서대로 작성합니다.
  3. 예외 상황도 테스트: 정상 케이스뿐 아니라 엣지 케이스도 고려합니다.
  4. 독립적인 테스트: 테스트 간 의존성을 없애야 합니다.

9. 권장 작성 방법

  • Given-When-Then 패턴 사용
  • 테스트 커버리지 도구 활용
  • CI/CD 파이프라인에 테스트 자동화 적용

10. 참고 사이트


단위 테스트는 코드 품질을 높이고 안정성을 유지하는 데 필수적인 도구입니다. NUnit과 JustMock을 활용해 효율적이고 체계적인 테스트를 작성해보세요!

profile
C#, .Net 개발자입니다.

0개의 댓글