unittest — 단위 테스트 프레임워크

unittest — 단위 테스트 프레임워크

unittest 모듈(파이썬 2.1 이전의 PyUnit에서 이름을 따옴)은 자바의 JUnit과 유사한, 테스트를 구성·실행하고 실행 결과를 확인하는 풍부한 단위 테스트 프레임워크예요. 객체지향 API를 제공하며, 테스트를 TestCase 하위 클래스로 작성하고 TestRunner로 실행해요. Python 배포판(예: test 디렉토리) 자체의 테스트도 이 모듈로 작성됐습니다.

이 문서는 전체 프레임워크를 다루는 포괄적인 참조예요. 단위 테스트 프레임워크 개념과 관련된 실용적인 내용은 함께 제공되는 튜토리얼을 참고하세요. unittest가 어떻게 테스트를 발견·실행·구성하는지 기존 코드 예제에서 보려면 Python 자체 테스트 스위트를 살펴보면 도움이 돼요. (예: Lib/test/test_json/, Lib/test/test_unittest.py)

출처: Python 표준 라이브러리 — unittest

본문

기본 사용 예시

unittest로 테스트 모듈을 작성하는 기본 형태는 이래요. 테스트는 unittest.TestCase를 상속한 클래스의 test로 시작하는 메서드로 만들고, 테스트 안에서 assertEqual() 같은 assertion 메서드로 결과를 확인합니다.

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

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

테스트는 각각 test_ prefix로 시작하는 메서드입니다. unittest.main()을 호출하면 자동으로 테스트를 발견·실행하고 결과를 리포트해요. 위 파일을 실행하면 작동('OK')하거나 실패한 테스트가 나열된 출력이 나옵니다.

테스트 구성 (Organizing test code)

단위 테스트는 단일 시나리오를 검증하는 코드 묶음으로 구성됩니다. 각 테스트는 고립된(다른 테스트와 독립적인) 방식으로 실행돼요. TestCase는 테스트가 끝난 뒤에 화면 출력을 캡처하거나, 데이터베이스 항목 같은 공유 자원을 정리하는 데 중요한 픽스처(fixture) 메서드를 제공합니다.

  • class unittest.TestCase(methodName='runTest') — 테스트에 사용되는 기본 클래스. 각 테스트 케이스는 test_로 시작하는 메서드로 구현되며, assertEqual(), assertTrue() 같은 assertion으로 기대 결과를 확인합니다.
  • setUp() — 각 테스트 메서드가 호출되기 전에 해당 테스트를 위한 환경을 준비하는 메서드. 하위 클래스에서 재정의.
  • tearDown() — 각 테스트 메서드가 끝난 뒤 정리하는 메서드. setUp()에서 성공적으로 호출됐다면 테스트가 실패하더라도 티어다운이 호출돼요.
  • setUpClass() — 클래스의 테스트 전에 한 번 호출되는 클래스 메서드(@classmethod setUpClass(cls)).
  • tearDownClass() — 클래스의 테스트가 모두 끝난 뒤 한 번 호출되는 클래스 메서드.
  • runTest() — 테스트를 수행하는 메서드. methodName 인자로 대체할 수 있어요.
import unittest

class WidgetTestCase(unittest.TestCase):
    def setUp(self):
        self.widget = Widget('The widget')

    def tearDown(self):
        self.widget.dispose()

    def test_default_widget_size(self):
        self.assertEqual(self.widget.size(), (50, 50))

assertion 메서드들 (Assertion methods)

TestCase는 다음과 같은 assertion 메서드들을 제공합니다.

  • assertEqual(a, b), assertNotEqual(a, b) — 동등/부등 비교.
  • assertTrue(x), assertFalse(x) — 참/거짓 확인.
  • assertIs(a, b), assertIsNot(a, b) — 정체성(identity) 비교.
  • assertIsNone(x), assertIsNotNone(x) — None 확인.
  • assertIn(a, b), assertNotIn(a, b) — 멤버십 확인.
  • assertIsInstance(a, b), assertNotIsInstance(a, b) — 인스턴스 확인.
  • assertRaises(exception, fun, *args, **kwds) — 예외 발생 확인 (context manager로 사용 가능).
  • assertRaisesRegex(exception, regex, fun=...) — 예외 + 메시지 정규식 확인.
  • assertWarns(warning, fun=...) — 경고 발생 확인.
  • assertAlmostEqual(a, b), assertNotAlmostEqual(a, b) — 근사 동등 비교.
  • assertGreater(a, b), assertGreaterEqual, assertLess, assertLessEqual — 대소 비교.
  • assertRegex(s, regex), assertNotRegex — 정규식 매칭.
  • assertCountEqual(a, b) — 순서 무관 동등(카운트) 비교.
  • assertMultiLineEqual, assertSequenceEqual, assertListEqual, assertTupleEqual, assertSetEqual, assertDictEqual — 컨테이너 비교.
  • fail(msg=None) — 무조건 실패.
self.assertEqual('foo'.upper(), 'FOO')     # PASS
with self.assertRaises(ValueError):          # 예외 기대
    int('abc')

경고·확인 헬퍼

  • assertLogs(logger=None, level=None) — 로그 메시지가 발생했는지 확인하는 context manager.
  • assertWarns / assertWarnsRegex — 경고 발생 확인.

테스트 실행 (Running tests)

테스트는 unittest.main()이나 python -m unittest 커맨드라인으로 실행할 수 있어요.

python -m unittest test_module1 test_module2
python -m unittest discover   # 재귀적으로 테스트 발견
python -m unittest -v test_module.TestClass.test_method
  • unittest.main(module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=..., verbosity=1, ...) — 테스트 실행을 위한 커맨드라인 프로그램.
  • 커맨드라인 옵션-v/--verbose(상세 출력), -q/--quiet, -f/--failfast(첫 실패에서 중단), -c/--catch(Ctrl-C 처리), -b/--buffer(stdout/stderr 버퍼), -k(서브스트링 매칭으로 테스트만 실행), --locals, -d/--debug 등.
  • 테스트 발견 (Test discovery)python -m unittest discovertest*.py 패턴으로 현재 디렉토리부터 재귀적으로 테스트 모듈을 찾아 실행해요. -s start, -p pattern, -t top_level_dir을 지정할 수 있어요.

스킵·예상 실패 (Skipping tests and expected failures)

  • @unittest.skip(reason) — 테스트를 건너뜀.
  • @unittest.skipIf(condition, reason) — 조건이 참이면 건너뜀.
  • @unittest.skipUnless(condition, reason) — 조건이 거짓이면 건너뜀.
  • @unittest.expectedFailure — 실패할 것으로 예상되는 테스트.
  • @unittest.SkipTest(reason) — 테스트 메서드 안에서 실행을 중단하고 스킵으로 표시.
@unittest.skip("demonstrating skipping")
def test_nothing(self):
    self.fail("shouldn't happen")

관련 클래스들 (Classes and functions)

  • class unittest.TestSuiteTestCase·TestSuite 개체의 모음. 테스트를 그룹으로 묶어 실행.
  • class unittest.TestResult — 단일 테스트 케이스에 대한 결과를 수집.
  • class unittest.TestLoader — 테스트 발견·로딩 담당 클래스.
  • class unittest.TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, ...) — 텍스트 기반 테스트 러너. 결과를 stream에 출력.
  • class unittest.TestProgramunittest.main()의 내부 구현 클래스.
  • unittest.defaultTestLoader — 기본 TestLoader 인스턴스.
  • unittest.skip(reason), unittest.skipIf, unittest.skipUnless, unittest.expectedFailure — 스킵 데코레이터.
  • class unittest.IsolatedAsyncioTestCase — 비동기(asyncio) 테스트 케이스 지원.
  • class unittest.FunctionTestCase — 기존 테스트 함수를 TestCase로 감싸는 클래스.
  • class unittest.mock — 목 객체를 만드는 mock 라이브러리.

예시 (Examples)

테스트가 성공·실패·오류로 나뉘는 과정과, unittest.main()을 실행한 결과 형식을 이해하는 데 유용한 예시가 원문에 있습니다.

  • 기본 예시 (위) — 성공 출력 ...OK / 실패 시 FAILED (failures=...) 출력.
  • python -m unittest -v로 상세 결과 확인.
  • discover로 테스트 발견.

더 알아보기