이 튜토리얼에서는 파이썬에 기본 내장된 unittest 모듈을 활용한 단위 테스트(Unit Testing) 방법을 알아봅니다. 테스팅은 소프트웨어 개발에서 매우 중요한 역할을 합니다. 코드를 실제 서비스 환경에 배포하기 전에 잠재적인 문제를 미리 발견하고 수정할 수 있게 해주기 때문입니다.
지금부터 파이썬 내장 모듈인 unittest를 사용해 테스트의 기본기를 차근차근 익혀보겠습니다.
단위 테스트란 무엇인가?
로그인 시스템을 예로 들어 보겠습니다. 로그인 폼을 구성하는 각 입력 필드(아이디, 비밀번호 등)가 하나의 단위(unit), 즉 컴포넌트입니다. 이처럼 프로그램을 이루는 개별 단위나 컴포넌트가 의도한 대로 올바르게 동작하는지 검증하는 작업을 단위 테스트(Unit Testing)라고 부릅니다.
unittest 프레임워크의 기본 구조
가장 먼저 unittest 프레임워크의 기본 골격을 살펴보겠습니다. 핵심 규칙은 테스트 메서드의 이름이 반드시 'test'로 시작해야 한다는 점입니다. unittest는 이 이름 규칙을 기준으로 실행할 테스트를 자동으로 찾아냅니다.
# importing unittest module
import unittest
# unittest will test all the methods whose name starts with 'test'
class SampleTest(unittest.TestCase):
# return True or False
def test(self):
self.assertTrue(True)
# running the test
unittest.main()실행 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
---------------------------------------------------------------------- Ran 1 test in 0.001s OK
출력 하단의 OK는 모든 테스트가 성공적으로 통과했다는 의미입니다.
문자열 메서드 테스트하기
이번에는 다양한 문자열 메서드를 샘플 테스트 케이스와 함께 검증해 보겠습니다. 앞서 언급했듯이 메서드 이름은 반드시 test로 시작해야 한다는 점을 기억하세요.
작성할 각 테스트 메서드의 역할은 다음과 같습니다.
test_string_equality
unittest.TestCase의 assertEqual 메서드를 사용해 두 문자열이 같은지 검증합니다.
test_string_case
assertEqual 메서드를 사용해 두 문자열의 대소문자 변환 결과가 일치하는지 확인합니다.
test_is_string_upper
assertTrue와 assertFalse 메서드를 사용해 문자열이 대문자인지 여부를 검증합니다.
예제 1: 통과하는 테스트 케이스
# importing unittest module
import unittest
class TestingStringMethods(unittest.TestCase):
# string equal
def test_string_equality(self):
# if both arguments are equal then it's success
self.assertEqual('ttp' * 5, 'ttpttpttpttpttp')
# comparing the two strings
def test_string_case(self):
# if both arguments are equal then it's success
self.assertEqual('tutorialspoint'.upper(), 'TUTORIALSPOINT')
# checking whether a string is upper or not
def test_is_string_upper(self):
# used to check whether the statement is True or False
# the result of expression inside the **assertTrue** must be True to pass the test case
# the result of expression inside the **assertFalse** must be False to pass the test case
self.assertTrue('TUTORIALSPOINT'.isupper())
self.assertFalse('TUTORIALSpoint'.isupper())
# running the tests
unittest.main()실행 결과
모든 테스트 케이스가 통과하면 아래와 같은 결과를 볼 수 있습니다.
... ---------------------------------------------------------------------- Ran 3 tests in 0.001s OK
출력 맨 위의 점(...)은 실행된 테스트의 개수를 나타내며, 점 하나당 테스트 하나가 성공했음을 의미합니다.
예제 2: 실패하는 테스트 케이스
이번에는 테스트가 실패했을 때 어떤 출력이 나오는지 확인해 보겠습니다. 아래 코드에서는 'TUTORIALSPOINt'처럼 소문자가 섞인 문자열에 대해 assertTrue를 호출하도록 일부러 수정했습니다.
# importing unittest module
import unittest
class TestingStringMethods(unittest.TestCase):
# string equal
def test_string_equality(self):
# if both arguments are equal then it's success
self.assertEqual('ttp' * 5, 'ttpttpttpttpttp')
# comparing the two strings
def test_string_case(self):
# if both arguments are equal then it's success
self.assertEqual('tutorialspoint'.upper(), 'TUTORIALSPOINT')
# checking whether a string is upper or not
def test_is_string_upper(self):
# used to check whether the statement is True or False
# the result of expression inside the **assertTrue** must be True to pass the test case
# the result of expression inside the **assertFalse** must be False to pass the test case
self.assertTrue('TUTORIALSPOINt'.isupper())
self.assertFalse('TUTORIALSpoint'.isupper())
# running the tests
unittest.main()실행 결과
위 프로그램을 실행하면 다음과 같은 실패 리포트가 출력됩니다.
======================================================================
FAIL: test_is_string_upper (__main__.TestingStringMethods)
----------------------------------------------------------------------
Traceback (most recent call last):
File "p:/Python Work/Stopwatch/practice.py", line 21, in test_is_string_upper
self.assertTrue('TUTORIALSPOINt'.isupper())
AssertionError: False is not true
----------------------------------------------------------------------
Ran 3 tests in 0.016s
FAILED (failures=1)여러 테스트 케이스 중 단 하나라도 실패하면 전체 결과가 FAILED로 표시되며, 어떤 테스트가 왜 실패했는지 상세한 추적 정보(traceback)가 함께 출력됩니다. 이 덕분에 문제가 된 지점을 빠르게 파악할 수 있습니다.
자주 사용하는 주요 단정문(Assertion) 메서드
unittest에는 위에서 사용한 것 외에도 다양한 단정문 메서드가 제공됩니다. 자주 쓰이는 메서드를 정리하면 다음과 같습니다.
| 메서드 | 설명 |
|---|---|
assertEqual(a, b) | a와 b가 같은지 검증 |
assertTrue(x) | x가 True인지 검증 |
assertFalse(x) | x가 False인지 검증 |
assertIn(a, b) | a가 b 안에 포함되어 있는지 검증 |
assertIsNone(x) | x가 None인지 검증 |
assertRaises(exc, func) | func 호출 시 exc 예외가 발생하는지 검증 |
마무리
이번 튜토리얼에서는 unittest 모듈의 기본 구조, 테스트 메서드 작성 규칙, 그리고 통과 및 실패 케이스의 출력 형태까지 살펴보았습니다. 단위 테스트는 코드 품질을 유지하고 리팩토링을 안전하게 진행할 수 있게 해주는 필수 습관입니다. 오늘 배운 내용을 직접 따라 하며 익혀보세요. 튜토리얼에 대해 궁금한 점이 있다면 댓글로 남겨주세요.