소프트웨어 개발에서 테스트는 코드의 품질과 안정성을 보장하는 핵심 과정입니다. 이 글에서는 Python 3.x에서 기본으로 제공되는 unittest 모듈을 활용해 단위 테스트(Unit Test)를 수행하는 방법을 알아보겠습니다. unittest는 테스트 자동화, 설정(setup) 및 종료(teardown) 코드의 공유, 프레임워크별 독립적인 테스트 작성을 지원합니다.
단위 테스트를 제대로 이해하려면 객체지향 개념에 대한 이해가 필요합니다. 그중에서도 가장 많이 사용되는 핵심 개념들을 살펴보겠습니다.
단위 테스트의 핵심 구성 요소
TestCase(테스트 케이스) — 주어진 입력값에 대한 응답을 검증하는 기본 클래스입니다. unittest의
TestCase클래스를 상속받아 구현합니다.TestSuite(테스트 스위트) — 여러 테스트 케이스를 하나로 묶어 한 번에 실행할 수 있게 해줍니다.
TestRunner(테스트 러너) — 결과 기반으로 작업을 실행하고, 실행 후 결과를 화면에 출력하는 역할을 담당합니다.
TestFixture(테스트 픽스처) — 연관된 환경에서 테스트 케이스가 수행되기 위한 기준선(baseline) 역할을 합니다.
기본 예제: 단위 테스트 동작 원리
간단한 예제를 통해 단위 테스트가 실제로 어떻게 작동하는지 확인해 보겠습니다.
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('TUTOR'.lower(), 'tutor')
def test_islower(self):
self.assertTrue('tutor'.islower())
self.assertFalse('Tutor'.islower())
if __name__ == '__main__':
unittest.main()실행 결과
.. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
위 예제에서는 단일 상속 방식으로 unittest의 TestCase 클래스를 확장했습니다. 여기서 사용된 주요 내장 메서드는 다음과 같습니다.
assertEqual() — 실제 출력값과 기대값을 비교하여 두 값이 일치하는지 검증합니다.
assertTrue() — 주어진 조건이 참(True)인지 확인합니다.
assertFalse() — 주어진 조건이 거짓(False)인지 확인합니다.
테스트 결과의 세 가지 형태
테스트 실행 결과는 크게 세 가지 형태로 나타납니다.
OK — 모든 테스트가 성공적으로 통과했음을 의미합니다.
FAIL — 테스트 케이스가 실패했으며
AssertionError예외가 발생했음을 나타냅니다.ERROR — 테스트 실행 중 예외나 오류가 발생했음을 나타냅니다.
특정 테스트 건너뛰기: @unittest.skip 데코레이터
상황에 따라 특정 테스트를 임시로 제외해야 할 때가 있습니다. 이럴 때 @unittest.skip(<reason>) 데코레이터를 사용하면 해당 테스트를 건너뛸 수 있습니다.
import unittest
class TestString(unittest.TestCase):
@unittest.skip("check skipped tests")
def test_upper(self):
self.assertEqual('TUTOR'.lower(), 'tutor')
def test_islower(self):
self.assertTrue('tutor'.islower())
self.assertFalse('Tutor'.islower())
if __name__ == '__main__':
unittest.main()실행 결과
s. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK (skipped=1)
결과에서 s는 skipped(건너뜀)를 의미하며, 마지막 줄에 건너뛴 테스트 수가 함께 표시됩니다.
마무리
이번 글에서는 Python 3.x의 unittest 모듈을 사용한 단위 테스트의 기본기를 살펴보았습니다. TestCase 상속, 다양한 assert 메서드, 테스트 결과 해석, skip 데코레이터까지 익히면 실제 프로젝트에서 안정적인 테스트 코드를 작성할 수 있습니다. 다음 단계로는 setUp()과 tearDown()을 활용한 테스트 픽스처 관리나 mock을 활용한 고급 테스트 기법을 학습해 보시길 권장합니다.