Python 고급

Python `unittest`를 이용한 단위 테스트 작성

PyExplorer 2025. 1. 14. 08:39
728x90

Python unittest를 이용한 단위 테스트 작성

소프트웨어 개발에서 단위 테스트(Unit Test)는 필수적인 과정입니다. 단위 테스트를 통해 코드의 개별 구성 요소가 의도한 대로 동작하는지 확인할 수 있습니다. Python은 표준 라이브러리로 unittest 모듈을 제공하며, 이를 사용하면 체계적이고 간단하게 단위 테스트를 작성할 수 있습니다. 이 포스팅에서는 unittest 모듈을 사용하여 단위 테스트를 작성하고 실행하는 방법을 예제와 함께 소개합니다.


1. 단위 테스트란?

단위 테스트는 프로그램의 가장 작은 단위(일반적으로 함수 또는 메서드)가 정확히 동작하는지 확인하는 테스트입니다. 단위 테스트는 다음과 같은 이점을 제공합니다:

  • 코드 품질 향상
  • 버그 조기 발견
  • 리팩토링 시 안전망 제공

Python의 unittest 모듈은 JUnit(Java)와 유사하며, 다음과 같은 기능을 제공합니다:

  • 테스트 케이스 작성 및 실행
  • 테스트 수트(Test Suite) 생성
  • 테스트 결과 리포트

2. unittest의 기본 구조

unittest로 테스트를 작성하려면 다음과 같은 기본 구조를 따라야 합니다:

  1. unittest.TestCase 클래스를 상속받은 클래스 정의
  2. 테스트 메서드 이름은 반드시 test_로 시작
  3. 다양한 단언문(assert)을 사용하여 테스트 조건 확인

예제: 간단한 덧셈 함수 테스트

# sum_utils.py

def add(a, b):
    return a + b

위의 add 함수를 테스트하려면 다음과 같은 단위 테스트를 작성할 수 있습니다:

# test_sum_utils.py
import unittest
from sum_utils import add

class TestAddFunction(unittest.TestCase):

    def test_add_positive_numbers(self):
        self.assertEqual(add(2, 3), 5)

    def test_add_negative_numbers(self):
        self.assertEqual(add(-1, -1), -2)

    def test_add_mixed_numbers(self):
        self.assertEqual(add(-1, 1), 0)

if __name__ == '__main__':
    unittest.main()

주요 부분 설명

  • TestCase 상속: unittest.TestCase를 상속받아 테스트 클래스를 생성합니다.
  • 테스트 메서드: test_로 시작하는 메서드는 테스트 메서드로 인식됩니다.
  • 단언문: assertEqual은 예상 결과와 실제 결과를 비교합니다.

3. 자주 사용하는 단언문

unittest는 다양한 단언문을 제공합니다. 몇 가지 주요 단언문은 다음과 같습니다:

단언문 설명
assertEqual(a, b) a == b 확인
assertNotEqual(a, b) a != b 확인
assertTrue(x) bool(x) is True 확인
assertFalse(x) bool(x) is False 확인
assertIs(a, b) a is b 확인
assertIsNot(a, b) a is not b 확인
assertIsNone(x) x is None 확인
assertIsNotNone(x) x is not None 확인
assertIn(a, b) a in b 확인
assertNotIn(a, b) a not in b 확인

예제: 단언문 활용

class TestAssertions(unittest.TestCase):

    def test_assertions(self):
        self.assertEqual(1 + 1, 2)
        self.assertTrue(3 > 2)
        self.assertIn('h', 'hello')

4. 테스트 실행 방법

Python에서 unittest를 실행하는 방법은 간단합니다:

  1. 터미널에서 실행:

    python -m unittest test_sum_utils.py
  2. 모든 테스트 실행:

    python -m unittest discover

discover 명령은 지정된 디렉토리에서 모든 테스트 파일(test_*.py)을 자동으로 검색합니다.


5. 테스트 수트(Test Suite) 만들기

테스트 수트를 사용하면 여러 테스트 케이스를 하나의 그룹으로 묶어 실행할 수 있습니다.

예제: 테스트 수트 생성

import unittest
from test_sum_utils import TestAddFunction
from test_other_module import TestOtherFunction

if __name__ == '__main__':
    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(TestAddFunction))
    suite.addTest(unittest.makeSuite(TestOtherFunction))

    runner = unittest.TextTestRunner()
    runner.run(suite)

6. Mock 객체를 이용한 테스트

실제 환경을 테스트할 수 없는 경우에는 Mock 객체를 활용할 수 있습니다. Python의 unittest.mock은 이러한 상황에 유용합니다.

예제: mock 사용하기

from unittest import TestCase
from unittest.mock import Mock

class TestMockExample(TestCase):

    def test_mock_method(self):
        mock_object = Mock()
        mock_object.some_method.return_value = 42

        result = mock_object.some_method()

        self.assertEqual(result, 42)
        mock_object.some_method.assert_called_once()

7. 실전 예제: 파일 처리 함수 테스트

# file_utils.py

def read_file(file_path):
    with open(file_path, 'r') as file:
        return file.read()

테스트 코드

# test_file_utils.py
import unittest
from unittest.mock import mock_open, patch
from file_utils import read_file

class TestFileUtils(unittest.TestCase):

    @patch('builtins.open', new_callable=mock_open, read_data='Hello, World!')
    def test_read_file(self, mock_file):
        result = read_file('dummy_path')
        self.assertEqual(result, 'Hello, World!')
        mock_file.assert_called_once_with('dummy_path', 'r')

if __name__ == '__main__':
    unittest.main()

8. 결론

이 포스팅에서는 Python의 unittest 모듈을 사용하여 단위 테스트를 작성하고 실행하는 방법을 살펴보았습니다. 단위 테스트는 안정적인 소프트웨어 개발의 핵심이며, unittest는 이를 구현하기 위한 강력한 도구를 제공합니다. 오늘 소개한 내용으로 여러분의 코드 품질을 더욱 높일 수 있기를 바랍니다.

728x90

'Python 고급' 카테고리의 다른 글

Python 코드 디버깅 기법  (0) 2025.01.16
Python pytest를 이용한 테스트 자동화  (0) 2025.01.15
Python 정기 작업 스케줄링  (0) 2025.01.13
Python 이메일 전송  (0) 2025.01.12
Python 파일 및 폴더 관리 자동화  (0) 2025.01.11