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

소스 코드: Lib/unittest/__init__.py


(당신이 이미 테스트 기본 개념에 친숙하다면, assert 메서드 목록으로 건너뛰어도 좋습니다.)

unittest 단위 테스트 프레임워크는 본래 JUnit으로부터 영감을 받고 다른 언어의 주요 단위 테스트 프레임워크와 비슷한 특징을 가지고 있습니다. 이것은 테스트 자동화, 테스트를 위한 사전 설정(setup)과 종료(shutdown) 코드 공유, 테스트를 컬렉션에 종합하기, 테스트와 리포트 프레임워크의 분리 등을 지원합니다.

이를 달성하기 위해 unittest는 객체 지향적인 방법으로 몇 가지 중요한 개념을 지원합니다.

테스트 픽스쳐

테스트 픽스쳐 (test fixture)는 1개 또는 그 이상의 테스트를 수행할 때 필요한 준비와 그와 관련된 정리 동작에 해당합니다. 예를 들어 이것은 임시 또는 프락시 데이터베이스, 디렉터리를 생성하거나 서버 프로세스를 시작하는 것 등을 포함합니다.

테스트 케이스

테스트 케이스(test case)는 테스트의 개별 단위입니다. 이것은 특정한 입력 모음에 대해서 특정한 결과를 확인합니다. unittest는 베이스 클래스인 TestCase를 지원합니다. 이 클래스는 새로운 테스트 케이스를 만드는 데 사용됩니다.

테스트 묶음

테스트 묶음(test suite)은 여러 테스트 케이스, 테스트 묶음, 또는 둘 다의 모임입니다. 이것은 서로 같이 실행되어야 할 테스트들을 종합하는 데 사용됩니다.

테스트 실행자

테스트 실행자(test runner)는 테스트 실행을 조율하고 테스트 결과를 사용자에게 제공하는 역할을 하는 컴포넌트입니다. 실행자는 테스트 실행 결과를 보여주기 위해 그래픽 인터페이스, 텍스트 인터페이스를 사용하거나 특별한 값을 반환할 수도 있습니다.

더 보기

doctest 모듈

매우 다른 특징을 가지고 있는 또 다른 테스트 지원 모듈

Simple Smalltalk Testing: With Patterns

unittest에 영향을 준 Kent Beck의 패턴을 사용한 테스트 프레임워크 원본 논문

pytest

Third-party unittest framework with a lighter-weight syntax for writing tests. For example, assert func(10) == 42.

파이썬 테스트 도구 분류

함수형 테스트 프레임워크와 모의 객체 라이브러리를 포함한 광범위한 파이썬 테스트 도구 목록

Testing in Python 메일링 리스트

파이썬에서 테스트하기와 테스트 도구에 대해 논의하는 특정-주제-그룹(special-interest-group)

파이썬 소스 배포판에 있는 Tools/unittestgui/unittestgui.py 스크립트는 테스트 탐색 및 실행을 위한 GUI 도구입니다. 이것은 단위 테스트가 처음인 사람들이 쉽게 사용할 수 있도록 만들어졌습니다. 라이브 환경에서는 Buildbot, Jenkins 또는 Hudson과 같은 지속적인 통합 시스템을 이용하여 테스트가 이루어지길 추천합니다.

기본 예시

unittest 모듈은 테스트를 구성하고 실행하는 데 풍부한 도구 모음을 제공하고 있습니다. 이 절에서는 대부분 사용자의 요구를 충족시키기 위해 일부 도구 모음만으로도 충분하다는 것을 보여줍니다.

문자열 관련된 3개의 메서드를 테스트하기 위한 짧은 스크립트가 여기에 있습니다:

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()

테스트 케이스는 unittest.TestCase를 서브 클래스 해서 생성하였습니다. 각각 3개의 테스트는 test 글자로 시작하는 이름을 가진 메서드로 정의했습니다. 이 명명 규칙은 테스트 실행자가 어떤 메서드가 테스트인지 알게 해줍니다.

각 테스트의 핵심은 기대되는 결과를 확인하기 위해 assertEqual()를 호출, 조건을 검증하기 위해 assertTrue() 또는 assertFalse()를 호출, 특정 예외가 발생했는지 검증하기 위해 assertRaises()를 호출하는 것입니다. assert 문장을 대신하여 이 메서드들을 사용하면 테스트 실행자가 모든 테스트 결과를 취합하여 리포트를 생성할 수 있습니다.

setUp()tearDown() 메서드로 각각의 테스트 메서드 전과 후에 실행될 명령어를 정의할 수 있습니다. 테스트 코드 구조 잡기에서 이것을 더 자세히 다루겠습니다.

마지막 블록은 테스트를 실행하는 간단한 방법을 보여줍니다. unittest.main()은 테스트 스크립트에 명령행 인터페이스를 제공합니다. 명령행에서 위 스크립트를 실행하면, 다음과 같은 출력이 나옵니다:

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

-v 옵션을 테스트 스크립트에 넘겨주게 되면 unittest.main()은 높은 상세도(verbosity)를 설정하여 그에 따른 출력이 나옵니다:

test_isupper (__main__.TestStringMethods) ... ok
test_split (__main__.TestStringMethods) ... ok
test_upper (__main__.TestStringMethods) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

위의 예시는 unittest에서 가장 자주 사용되는 기능을 보여주며 이것은 많은 일상적인 테스트 요구 사항을 충족시키기에 충분합니다. 문서의 나머지 부분은 기초부터 시작해서 모든 기능을 살펴봅니다.

명령행 인터페이스

unittest 모듈은 명령행을 사용하여 모듈, 클래스, 심지어 각 테스트 메서드의 테스트들을 실행할 수 있습니다:

python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method

모듈 이름이나 완전히 정규화된 클래스나 메서드 이름이 포함된 목록을 전달할 수 있습니다.

테스트 모듈은 파일 경로로도 지정할 수 있습니다:

python -m unittest tests/test_something.py

이것으로 테스트 모듈을 지정할 때 셸(shell)의 파일 이름 완성 기능을 사용할 수 있습니다. 지정된 파일은 반드시 모듈로 임포트 가능해야 합니다. 파일 경로는 ‘.py’ 가 빠지면서 모듈 이름으로 변경되고 경로 구분자도 ‘.’로 변경됩니다. 만약 당신이 임포트 가능하지 않은 테스트 파일을 모듈로 사용하고 싶으시다면 이 방법 대신에 그 파일을 직접 실행해야 합니다.

-v 옵션을 사용하여 더 자세한 정보(높은 상세도)로 테스트를 실행할 수 있습니다:

python -m unittest -v test_module

아무 인자 없이 실행하면 테스트 탐색(Discovery)이 실행됩니다:

python -m unittest

모든 명령행 옵션 목록을 보기:

python -m unittest -h

버전 3.2에서 변경: 이전 버전에서는 개별 테스트 메서드만 실행이 가능했고, 모듈과 클래스는 불가능했습니다.

명령행 옵션

unittest는 다음과 같은 명령행 옵션을 제공합니다:

-b, --buffer

테스트가 실행될 동안 표준 출력과 표준 에러 스트림이 버퍼링 됩니다. 통과한 테스트 중에 나온 출력은 버려집니다. 보통 테스트 실패나 에러에서 나온 출력은 표시되고 실패 메시지에 추가됩니다.

-c, --catch

테스트 실행 중에 Control-C를 누르면 현재 테스트가 끝날 때까지 기다린 다음 지금까지의 모든 결과를 보고합니다. Control-C를 다시 누르면 일반적인 KeyboardInterrupt 예외를 발생합니다.

이 기능과 관련된 함수는 시그널 처리하기를 참고하십시오.

-f, --failfast

첫 번째 에러나 실패가 발생하면 테스트 실행을 중단합니다.

-k

패턴이나 부분 문자열과 일치하는 테스트 메서드나 클래스만 실행합니다. 이 옵션은 여러 번 사용될 수 있습니다. 이 경우 주어진 패턴과 일치하는 모든 테스트 케이스가 포함됩니다.

와일드카드 문자(*)를 포함한 패턴은 fnmatch.fnmatchcase()를 사용하여 그에 일치하는 테스트 이름을 찾고; 그렇지 않은 경우 단순히 대소문자를 구별하는 부분 문자열 일치가 사용됩니다.

패턴을 테스트 로더가 임포트한 완전히 정규화된 테스트 메서드 이름과 대조합니다.

예를 들어 -k foofoo_tests.SomeTest.test_something, bar_tests.SomeTest.test_foo에 일치하지만, bar_tests.FooTest.test_something에는 일치하지 않습니다.

--locals

트레이스백(traceback)에서 지역 변수를 표시합니다.

버전 3.2에 추가: 명령행 옵션인 -b, -c, -f가 추가되었습니다.

버전 3.5에 추가: 명령행 옵션 --locals.

버전 3.7에 추가: 명령행 옵션 -k.

명령행은 프로젝트의 모든 테스트 또는 일부분의 테스트 탐색을 위해서도 사용할 수 있습니다.

테스트 탐색(Discovery)

버전 3.2에 추가.

unittest는 간단한 테스트 탐색을 지원합니다. 테스트 탐색에 호환되기 위해서는 모든 테스트 파일은 반드시 프로젝트의 가장 상위 디렉터리로부터 모듈 또는 패키지(이름 공간 패키지 포함)로 임포트 가능해야 합니다(이 말은 파일 이름이 반드시 유효한 식별자이어야 한다는 뜻입니다).

테스트 탐색은 TestLoader.discover()로 구현되어 있습니다, 그러나 명령행으로 사용할 수도 있습니다. 기본적인 명령행 사용법은 다음과 같습니다:

cd project_directory
python -m unittest discover

참고

단축형인 python -m unittestpython -m unittest discover와 같습니다. 테스트 탐색에 인자를 전달하고 싶을 때는 discover 부속 명령어(sub-command)를 명시적으로 사용해야 합니다.

discover 부-명령어는 다음과 같은 옵션을 가지고 있습니다:

-v, --verbose

상세한 출력

-s, --start-directory directory

탐색을 시작할 디렉터리(기본값 .)

-p, --pattern pattern

테스트 파일을 검색할 패턴(기본값 test*.py)

-t, --top-level-directory directory

프로젝트의 최상위 디렉터리(기본값 시작 디렉터리)

-s, -p, -t 옵션은 이 순서대로 위치 인자로서 사용할 수 있습니다. 다음 2개의 명령행은 같습니다:

python -m unittest discover -s project_directory -p "*_test.py"
python -m unittest discover project_directory "*_test.py"

경로가 사용되는 곳에 패키지 이름을 전달하는 것도 가능합니다, 예를 들어 myproject.subpackage.test를 시작 디렉터리로 사용할 수 있습니다. 주어진 패키지 이름은 임포트되어 그것의 파일 시스템상의 위치를 시작 디렉터리로 사용하게 됩니다.

조심

테스트 탐색은 테스트를 임포트하여 로드합니다. 테스트 탐색이 당신이 지정한 시작 디렉터리로부터 모든 테스트 파일을 찾았다면 임포트하기 위해 그 파일 경로를 패키지 이름으로 바꿉니다. 예를 들어 foo/bar/baz.pyfoo.bar.baz로 임포트될 것입니다.

만약 당신이 전역적으로 설치된 패키지가 있고 테스트 탐색을 다른 패키지 복사본에 하려고 시도한다면 임포트가 잘못된 위치에서 발생할 수도 있습니다. 만약 이런 일이 발생한다면 테스트 탐색은 경고하고 종료될 것입니다.

만약 당신이 시작 디렉터리로 경로가 아닌 패키지 이름을 전달했다면 테스트 탐색은 임포트가 어느 경로로부터 되었든 간에 당신이 의도한 경로라고 간주하여 경고를 발생하지 않을 것입니다.

테스트 모듈과 패키지는 load_tests 프로토콜을 통하여 테스트 로드와 탐색을 사용자 정의할 수 있습니다.

버전 3.4에서 변경: 테스트 탐색은 이름 공간 패키지를 지원합니다.

테스트 코드 구조 잡기

단위 테스트의 기본 구성 블록은 테스트 케이스(test cases) — 정확성을 위해 설정되고 확인될 하나의 시나리오입니다. unittest에서 테스트 케이스는 unittest.TestCase 인스턴스에 해당합니다. 당신만의 테스트 케이스를 만들기 위해서는 TestCase의 서브 클래스를 작성하거나 FunctionTestCase를 사용해야 합니다.

TestCase 인스턴스의 테스트 코드는 완전히 독립적으로 되어 있어야 합니다, 그래야지 이것을 각각 단독으로 실행하거나 다른 여러 테스트 케이스와 함께 임의의 조합으로 실행할 수 있습니다.

가장 간단한 TestCase의 서브 클래스는 특정 테스트 코드를 수행하도록 단순히 테스트 메서드(즉 test로 이름이 시작하는 함수)를 구현하는 것입니다:

import unittest

class DefaultWidgetSizeTestCase(unittest.TestCase):
    def test_default_widget_size(self):
        widget = Widget('The widget')
        self.assertEqual(widget.size(), (50, 50))

어떤 것을 테스트하기 위해서는 TestCase 베이스 클래스에서 제공하는 assert*() 메서드 중 한 개를 사용합니다. 테스트가 실패한다면 그 이유를 설명한 메시지가 포함된 예외가 발생합니다, 그리고 unittest는 해당 테스트 케이스를 실패(failure)로 취급합니다. 다른 모든 예외는 에러(errors)로 취급합니다.

테스트는 매우 많지만, 그것을 위한 사전 설정은 계속 반복될 수 있습니다. 다행히, setUp()이란 메서드를 작성하여 사전 설정 코드를 밖으로 분리해낼 수 있습니다. 테스트 프레임워크가 1개의 테스트마다 매번 자동으로 이것을 호출할 것입니다:

import unittest

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

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

    def test_widget_resize(self):
        self.widget.resize(100,150)
        self.assertEqual(self.widget.size(), (100,150),
                         'wrong size after resize')

참고

다양한 테스트가 실행될 순서는 테스트 메서드의 이름을 가지고 내장된 문자열 정렬 순서에 의하여 결정될 것입니다.

만약 setUp() 메서드가 테스트 실행 중에 예외를 발생시킨다면 프레임워크는 테스트에 오류가 있는 것으로 간주하여 테스트 메서드를 실행하지 않을 것입니다.

마찬가지로 테스트 메서드가 실행되고 나서 정리하기 위해 tearDown() 메서드를 제공합니다:

import unittest

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

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

만약 setUp()이 성공했다면, 테스트가 성공했든 실패했든 상관없이 tearDown()이 실행될 것입니다.

이와 같은 테스트를 위한 실행 환경을 테스트 픽스쳐(test fixture)라고 부릅니다. 개별 테스트 메서드를 실행하기 위해 고유한 테스트 픽스쳐에 해당하는 새로운 테스트 케이스 인스턴스가 생성됩니다. 따라서 setUp(), tearDown(), __init__()는 테스트 당 1번씩 실행됩니다.

테스트하려는 기능에 따라 테스트들을 같이 모아서 테스트 케이스 구현을 사용하는 것을 추천합니다. 이것을 위해 unittest는 메커니즘을 제공합니다: 테스트 묶음(test suite), 이것은 unittestTestSuite 클래스에 해당합니다. 대부분의 경우 unittest.main()이 테스트를 실행하기 위해 모듈의 모든 테스트 케이스를 수집하여 적절한 행동을 취할 것입니다.

그러나 당신이 테스트 묶음을 사용자 정의하고 싶다면 그것을 직접 만들어야 합니다:

def suite():
    suite = unittest.TestSuite()
    suite.addTest(WidgetTestCase('test_default_widget_size'))
    suite.addTest(WidgetTestCase('test_widget_resize'))
    return suite

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(suite())

당신은 테스트 케이스와 테스트 묶음의 정의를 테스트하려는 코드와 같은 모듈(예를 들어 file:widget.py)에 넣을 수 있습니다, 그러나 테스트 코드를 분리된 모듈(예를 들어 test_widget.py)에 넣으면 몇 가지 이점이 있습니다:

  • 테스트 모듈이 명령행에서 독립적으로 작동할 수 있습니다.

  • 테스트 코드가 배포될 코드와 쉽게 분리될 수 있습니다.

  • 충분한 이유 없이 테스트하려는 코드에 맞춰서 테스트 코드를 바꾸려는 유혹이 덜 합니다.

  • 테스트 코드가 테스트하려는 코드에 비해 훨씬 덜 빈번하게 수정되어야 합니다.

  • 테스트하려는 코드는 더 쉽게 리팩토링할 수 있습니다.

  • C 언어로 작성된 모듈의 테스트 코드는 반드시 분리된 모듈에 위치해야 합니다, 따라서 일관성을 지키는 것이 어떨까요?

  • 만약 테스트 전략이 바뀌더라도 소스 코드를 바꿀 필요가 없습니다.

이전의 테스트 코드를 다시 사용하기

어떤 사용자들은 이전의 모든 테스트 함수를 TestCase 서브 클래스로 변경하는 작업 없이 기존의 테스트 코드를 unittest로 실행하고 싶어 할 것입니다.

이러한 이유로 unittestFunctionTestCase 클래스를 제공합니다. 이 TestCase의 서브 클래스는 기존 테스트 함수를 감싸는데 사용할 수 있습니다. 사전 설정과 정리 함수 또한 같이 사용할 수 있습니다.

다음과 같은 테스트 함수가 있을 때:

def testSomething():
    something = makeSomething()
    assert something.name is not None
    # ...

다음과 같이 동등한 테스트 케이스 인스턴스를 생성할 수 있습니다, 추가로 사전 설정과 정리 메서드를 함께 설정합니다:

testcase = unittest.FunctionTestCase(testSomething,
                                     setUp=makeSomethingDB,
                                     tearDown=deleteSomethingDB)

참고

FunctionTestCase를 사용하여 기존 테스트를 unittest-기반 시스템으로 빠르게 변경할 수 있을지라도 이 방법을 추천하지는 않습니다. 시간을 들여서 적절한 TestCase 서브 클래스를 설정하는 것이 미래에 있을 테스트 리팩토링을 대단히 쉽게 만들어줄 것입니다.

어떤 경우에는 doctest 모듈을 사용하여 기존 테스트가 작성되었을 수도 있습니다. 만약 그렇다면 doctest가 제공하는 DocTestSuite 클래스를 사용하여 기존의 doctest-기반 테스트로부터 unittest.TestSuite 인스턴스를 자동으로 만들 수 있습니다.

테스트 건너뛰기와 예상된 실패

버전 3.1에 추가.

unittest는 테스트 중에서 개별 테스트 메서드나 심지어 전체 클래스를 건너뛸 수 있는 기능을 제공합니다. 게다가 테스트를 “예상된 실패”로 표시하는 기능도 지원합니다, 테스트가 망가져서 실패하더라도 그것을 TestResult에 실패라고 기록하지 않습니다.

테스트 건너뛰기는 단순히 skip() 데코레이터나 그것의 조건 변형 중 하나를 사용하거나, setUp()이나 테스트 메서드 안에서 TestCase.skipTest()를 호출하거나, SkipTest를 직접 발생시키면 됩니다.

기본적인 건너뛰기는 다음과 같습니다:

class MyTestCase(unittest.TestCase):

    @unittest.skip("demonstrating skipping")
    def test_nothing(self):
        self.fail("shouldn't happen")

    @unittest.skipIf(mylib.__version__ < (1, 3),
                     "not supported in this library version")
    def test_format(self):
        # Tests that work for only a certain version of the library.
        pass

    @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
    def test_windows_support(self):
        # windows specific testing code
        pass

    def test_maybe_skipped(self):
        if not external_resource_available():
            self.skipTest("external resource not available")
        # test code that depends on the external resource
        pass

아래는 위의 예를 상세 모드로 실행했을 때의 출력입니다:

test_format (__main__.MyTestCase) ... skipped 'not supported in this library version'
test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping'
test_maybe_skipped (__main__.MyTestCase) ... skipped 'external resource not available'
test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows'

----------------------------------------------------------------------
Ran 4 tests in 0.005s

OK (skipped=4)

클래스도 메서드처럼 건너뛰기가 가능합니다:

@unittest.skip("showing class skipping")
class MySkippedTestCase(unittest.TestCase):
    def test_not_run(self):
        pass

TestCase.setUp() 또한 테스트를 건너뛸 수 있습니다. 이것은 사전 설정해야 할 자원을 사용할 수 없을 때 유용합니다.

예상된 실패는 expectedFailure() 데코레이터를 사용합니다.

class ExpectedFailureTestCase(unittest.TestCase):
    @unittest.expectedFailure
    def test_fail(self):
        self.assertEqual(1, 0, "broken")

자신만의 건너뛰기 데코레이터를 만들기는 쉽습니다. 테스트를 건너뛰고 싶을 때 skip()를 호출하도록 데코레이터를 만들면 됩니다. 다음의 데코레이터는 특정 어트리뷰트가 있는 객체가 전달되지 않으면 테스트를 건너뜁니다:

def skipUnlessHasattr(obj, attr):
    if hasattr(obj, attr):
        return lambda func: func
    return unittest.skip("{!r} doesn't have {!r}".format(obj, attr))

다음 데코레이터들과 예외는 테스트 건너뛰기와 예상된 실패를 구현합니다:

@unittest.skip(reason)

조건 없이 데코레이트된 테스트를 건너뜁니다. reason은 왜 이 테스트가 건너뛰어 졌는지를 설명해야 합니다.

@unittest.skipIf(condition, reason)

condition이 참이면 데코레이트된 테스트를 건너뜁니다.

@unittest.skipUnless(condition, reason)

condition이 참이 아니면 데코레이트된 테스트를 건너뜁니다.

@unittest.expectedFailure

테스트가 예상된 실패라는 표시를 합니다. 테스트가 실패하면 성공으로 간주합니다. 테스트에 통과하면 실패로 간주합니다.

exception unittest.SkipTest(reason)

이 예외는 테스트를 건너뛰기 위해서 발생합니다.

보통은 이 예외를 직접 발생시키기보다는 TestCase.skipTest()나 건너뛰기 데코레이터를 사용할 수 있습니다.

건너뛰는 테스트는 테스트 전후로 setUp()이나 tearDown()를 실행하지 않을 것입니다. 건너뛰는 클래스는 setUpClass()tearDownClass()를 실행하지 않을 것입니다. 건너뛰는 모듈은 setUpModule()이나 tearDownModule()을 실행하지 않을 것입니다.

부분 테스트(subtest)를 사용하여 테스트 반복 구별 짖기

버전 3.4에 추가.

여러분의 테스트들이 아주 작은 부분에서만 다를 때, 예를 들어 몇몇 매개변수, unittest는 subTest() 컨텍스트 관리자를 사용하여 테스트 메서드의 바디 안에서 그것들은 구별 짖게 해줍니다.

예를 들어, 다음 테스트는:

class NumbersTest(unittest.TestCase):

    def test_even(self):
        """
        Test that numbers between 0 and 5 are all even.
        """
        for i in range(0, 6):
            with self.subTest(i=i):
                self.assertEqual(i % 2, 0)

다음의 출력을 만듭니다:

======================================================================
FAIL: test_even (__main__.NumbersTest) (i=1)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 32, in test_even
    self.assertEqual(i % 2, 0)
AssertionError: 1 != 0

======================================================================
FAIL: test_even (__main__.NumbersTest) (i=3)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 32, in test_even
    self.assertEqual(i % 2, 0)
AssertionError: 1 != 0

======================================================================
FAIL: test_even (__main__.NumbersTest) (i=5)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 32, in test_even
    self.assertEqual(i % 2, 0)
AssertionError: 1 != 0

부분 테스트를 사용하지 않는다면 테스트 실행은 첫 번째 실패 후에 중단될 것이고 i 값이 표시되지 않기 때문에 에러를 진단하는 데 쉽지 않을 것입니다:

======================================================================
FAIL: test_even (__main__.NumbersTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 32, in test_even
    self.assertEqual(i % 2, 0)
AssertionError: 1 != 0

클래스와 함수

이 절은 unittest의 API를 심도 있게 설명합니다.

테스트 케이스

class unittest.TestCase(methodName='runTest')

TestCase 클래스의 인스턴스는 unittest 세계에서 논리적인 테스트 단위에 해당합니다. 이 클래스는 베이스 클래스로 사용되며, 특정 테스트는 구상 클래스로 구현됩니다. 이 클래스는 테스트 실행자가 테스트를 실행할 수 있는 인터페이스를 구현하고 테스트 코드가 검사하고 다양한 실패를 보고할 수 있는 메서드를 구현합니다.

TestCase의 각 인스턴스는 하나의 베이스 메서드: methodName이 지정하는 이름의 메서드를 실행할 것입니다. 대부분의 TestCase 사용에서, 당신은 methodName을 바꾸거나 기본 runTest() 메서드를 재구현하지 않을 것입니다.

버전 3.2에서 변경: methodName 제공 없이도 TestCase를 성공적으로 인스턴스화할 수 있습니다. 이것은 대화형 인터프리터에서 TestCase로 쉽게 실험을 할 수 있게 합니다.

TestCase 인스턴스는 3가지 메서드 그룹을 제공합니다: 한 그룹은 테스트를 실행하는 데 사용되고, 다른 한 그룹은 조건을 확인하고 실패를 보고하는 테스트 구현으로 사용되고, 몇몇 조회 메서드는 테스트 자체에 관한 정보를 수집할 수 있게 해줍니다.

첫 번째 그룹(테스트 실행) 안에 메서드는:

setUp()

테스트 픽스쳐를 준비하기 위해 호출되는 메서드입니다. 이 메서드는 테스트 메서드를 호출하기 바로 직전에 호출됩니다; AssertionError 또는 SkipTest이외의 이 메서드에서 발생한 모든 예외는 테스트 실패가 아닌 오류로 간주합니다. 기본 구현은 아무것도 하지 않습니다.

tearDown()

테스트 메서드가 불리고 결과가 기록되고 나서 바로 다음에 호출되는 메서드입니다. 테스트 메서드가 예외를 발생했더라도 이 메서드는 불립니다, 따라서 서브 클래스의 구현은 내부 상태를 확인하는 데 특별히 주의를 기울여야 합니다. AssertionError 또는 SkipTest이외의 이 메서드에서 발생하는 모든 예외는 테스트 실패가 아닌 오류로 간주합니다(따라서 보고된 오류의 총 숫자가 증가합니다). 이 메서드는 테스트 메서드의 결과물에 영향받지 않고 setUp()이 성공했을 때만 불립니다. 기본 구현은 아무것도 하지 않습니다.

setUpClass()

개별 클래스의 테스트들이 실행되기 전에 불리는 클래스 메서드입니다. setUpClass는 클래스만 인자로 받아 호출되고 classmethod()로 데코레이트해야 합니다:

@classmethod
def setUpClass(cls):
    ...

더 자세한 것은 클래스와 모듈 픽스쳐를 보십시오.

버전 3.2에 추가.

tearDownClass()

개별 클래스의 테스트들이 실행되고 난 뒤에 불리는 클래스 메서드입니다. tearDownClass는 클래스만 인자로 받아 호출되고 classmethod()로 데코레이트해야 합니다:

@classmethod
def tearDownClass(cls):
    ...

더 자세한 것은 클래스와 모듈 픽스쳐를 보십시오.

버전 3.2에 추가.

run(result=None)

테스트를 실행하고, result 인자로 전달된 TestResult에 결과를 수집합니다. 만약 result 인자가 전달 안 되거나 None이라면 임시 결과 객체를 (defaultTestResult() 메서드를 불러서) 생성하여 사용합니다. run() 호출자에게 결과 객체를 반환합니다.

단순히 TestCase 인스턴스를 호출하는 것으로 같은 효과를 볼 수 있습니다.

버전 3.3에서 변경: 기존 버전의 run은 결과를 반환하지 않았습니다. 인스턴스 호출 또한 그렇지 않았습니다.

skipTest(reason)

테스트 메서드나 setUp()에서 이것을 호출하면 현재 테스트를 건너뜁니다. 자세한 정보는 테스트 건너뛰기와 예상된 실패를 보십시오.

버전 3.1에 추가.

subTest(msg=None, **params)

둘러싼 코드 블록을 부분 테스트로서 실행하는 컨텍스트 관리자를 반환합니다. msgparams는 선택 사항이며 부분 테스트가 실패 할 때마다 표시되는 임의의 값으로 당신이 명확하게 알아보게 해줍니다.

테스트 케이스는 여러 개의 부분 테스트 선언을 포함할 수 있고, 그것들은 자유롭게 중첩될 수 있습니다.

자세한 정보는 부분 테스트(subtest)를 사용하여 테스트 반복 구별 짖기를 보십시오.

버전 3.4에 추가.

debug()

결과를 수집하지 않고 테스트를 실행합니다. 이것은 테스트에서 발생한 예외가 호출자로 전파될 수 있게 해서, 디버거 환경에서 테스트를 실행할 때 사용될 수 있습니다.

TestCase 클래스는 값을 검사하고 실패를 보고하기 위해 몇 개의 assert 메서드를 제공합니다. 다음 표는 보통 많이 사용되는 메서드들입니다(더 많은 assert 메서드는 표 아래를 보십시오):

메서드

검사하는 내용

추가된 버전

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

3.1

assertIsNot(a, b)

a is not b

3.1

assertIsNone(x)

x is None

3.1

assertIsNotNone(x)

x is not None

3.1

assertIn(a, b)

a in b

3.1

assertNotIn(a, b)

a not in b

3.1

assertIsInstance(a, b)

isinstance(a, b)

3.2

assertNotIsInstance(a, b)

not isinstance(a, b)

3.2

모든 assert 메서드는 msg 인자를 받을 수 있습니다, 만약 그것이 전달된다면 실패 시 에러 메시지로 사용됩니다(longMessage 도 참고하십시오). assertRaises(), assertRaisesRegex(), assertWarns(), assertWarnsRegex()는 컨텍스트 관리자로서 사용될 때만 그들에게 msg 키워드 인자를 전달할 수 있다는 점을 주의하십시오.

assertEqual(first, second, msg=None)

firstsecond가 같은지 테스트합니다. 비교한 값이 같지 않으면 테스트는 실패할 것입니다.

추가로, 만약 firstsecond가 정확히 같은 형(type)이고 list, tuple, dict, set, frozenset, str 이거나 addTypeEqualityFunc()에 등록된 서브 클래스 형 중 하나일 경우 더 유용한 기본 에러 메시지를 생성하기 위해 형-특화(type-specific) 동등성 함수가 불릴 것입니다(형-특화 메서드 목록을 참고하십시오).

버전 3.1에서 변경: 형-특화 동등성 함수가 자동으로 불리도록 추가

버전 3.2에서 변경: 문자열 비교를 위해서 assertMultiLineEqual()를 기본 형-특화 동등성 함수에 추가

assertNotEqual(first, second, msg=None)

firstsecond가 같지 않은지 테스트합니다, 비교한 값이 같으면 테스트는 실패할 것입니다.

assertTrue(expr, msg=None)
assertFalse(expr, msg=None)

expr이 참(또는 거짓)인지 테스트합니다.

이것은 bool(expr) is True와 동등하고 expr is True와 동등하지 않다는 것에 주의하십시오(후자를 위해선 assertIs(expr, True)를 사용하십시오). 더 구체적인 메서드를 사용할 수 있을 때는 이 메서드를 지양해야 합니다(예, assertTrue(a == b) 대신에 assertEqual(a, b)), 왜냐하면 실패의 경우에 구체적인 메서드가 더 나은 에러 메시지를 제공하기 때문입니다.

assertIs(first, second, msg=None)
assertIsNot(first, second, msg=None)

firstsecond가 같은 객체로 평가되는지(아닌지) 테스트합니다.

버전 3.1에 추가.

assertIsNone(expr, msg=None)
assertIsNotNone(expr, msg=None)

exprNone 인지(아닌지) 테스트합니다.

버전 3.1에 추가.

assertIn(member, container, msg=None)
assertNotIn(member, container, msg=None)

Test that member is (or is not) in container.

버전 3.1에 추가.

assertIsInstance(obj, cls, msg=None)
assertNotIsInstance(obj, cls, msg=None)

objcls(isinstance()가 지원하는 것처럼 클래스 또는 클래스의 튜플)의 인스턴스인지(아닌지) 테스트합니다. 정확한 형 검사를 위해서는 assertIs(type(obj), cls)를 사용하십시오.

버전 3.2에 추가.

다음의 메서드를 사용하여 예외, 경고, 로그 메시지의 발생을 검사할 수 있습니다:

메서드

검사하는 내용

추가된 버전

assertRaises(exc, fun, *args, **kwds)

fun(*args, **kwds)exc를 발생

assertRaisesRegex(exc, r, fun, *args, **kwds)

fun(*args, **kwds)exc를 발생하고 메시지가 정규식 r에 일치

3.1

assertWarns(warn, fun, *args, **kwds)

fun(*args, **kwds)warn을 발생

3.2

assertWarnsRegex(warn, r, fun, *args, **kwds)

fun(*args, **kwds)warn을 발생하고 메시지가 정규식 r에 일치

3.2

assertLogs(logger, level)

with 블록이 최소 levellogger에 로그를 남김

3.4

assertRaises(exception, callable, *args, **kwds)
assertRaises(exception, *, msg=None)

assertRaises()에 전달된 어떤 위치 또는 키워드 인자와 함께 callable이 호출되었을 때 예외가 발생하는지 테스트합니다. exception이 발생하면 테스트를 통과하고, 다른 예외가 발생하면 에러이고, 아무 예외도 발생하지 않으면 실패입니다. 여러 예외 모음을 잡기 위해서 예외 클래스를 포함한 튜플을 exception으로 전달해도 좋습니다.

만약 선택적인 msg와 함께 오직 exception 인자만 전달된다면, 테스트할 코드를 함수가 아닌 인라인으로 작성할 수 있도록 컨텍스트 관리자를 반환합니다:

with self.assertRaises(SomeException):
    do_something()

컨텍스트 관리자로 사용되면, assertRaises()는 추가적인 키워드 인자인 msg를 받을 수 있습니다.

컨텍스트 관리자는 잡은 예외 객체를 exception 어트리뷰트에 저장할 것입니다. 이것은 발생한 예외에 대해서 추가적인 검사를 수행하려는 경우에 유용할 수 있습니다:

with self.assertRaises(SomeException) as cm:
    do_something()

the_exception = cm.exception
self.assertEqual(the_exception.error_code, 3)

버전 3.1에서 변경: assertRaises()를 컨텍스트 관리자로 사용할 수 있도록 기능 추가.

버전 3.2에서 변경: exception 어트리뷰트 추가.

버전 3.3에서 변경: 컨텍스트 관리자로 사용될 때 msg 키워드 인자 추가.

assertRaisesRegex(exception, regex, callable, *args, **kwds)
assertRaisesRegex(exception, regex, *, msg=None)

assertRaises()와 비슷하지만 발생한 예외의 문자열 표현이 regex에 일치하는지 테스트합니다. regex는 정규식 객체나 re.search()에 사용되기 적합한 정규식 문자열이 될 수 있습니다. 예:

self.assertRaisesRegex(ValueError, "invalid literal for.*XYZ'$",
                       int, 'XYZ')

또는:

with self.assertRaisesRegex(ValueError, 'literal'):
   int('XYZ')

버전 3.1에 추가: assertRaisesRegexp 라는 이름으로 추가되었습니다.

버전 3.2에서 변경: assertRaisesRegex()으로 이름 변경.

버전 3.3에서 변경: 컨텍스트 관리자로 사용될 때 msg 키워드 인자 추가.

assertWarns(warning, callable, *args, **kwds)
assertWarns(warning, *, msg=None)

assertWarns()에 전달된 어떤 위치 또는 키워드 인자와 함께 callable이 호출되었을 때 경고(warning)가 발생하는지 테스트합니다. warning이 발생하면 테스트를 통과하고, 그렇지 않으면 실패입니다. 예외가 발생하면 에러입니다. 여러 경고 모음을 잡기 위해서 경고 클래스를 포함한 튜플을 warnings로 전달해도 좋습니다.

만약 선택적인 msg와 함께 오직 warning 인자만 전달된다면, 테스트할 코드를 함수가 아닌 인라인으로 작성할 수 있도록 컨텍스트 관리자를 반환합니다:

with self.assertWarns(SomeWarning):
    do_something()

컨텍스트 관리자로 사용되면, assertWarns()는 추가적인 키워드 인자인 msg를 받을 수 있습니다.

컨텍스트 관리자는 잡은 경고 객체를 warning 어트리뷰트에 저장하고, 경고를 발생한 소스코드 줄을 filenamelineno에 저장할 것입니다. 이것은 발생한 경고에 대해서 추가적인 검사를 수행하려는 경우에 유용할 수 있습니다:

with self.assertWarns(SomeWarning) as cm:
    do_something()

self.assertIn('myfile.py', cm.filename)
self.assertEqual(320, cm.lineno)

이 메서드는 호출될 때 적용될 경고 필터와 관계없이 작동합니다.

버전 3.2에 추가.

버전 3.3에서 변경: 컨텍스트 관리자로 사용될 때 msg 키워드 인자 추가.

assertWarnsRegex(warning, regex, callable, *args, **kwds)
assertWarnsRegex(warning, regex, *, msg=None)

assertWarns()와 비슷하지만 발생한 경고의 메시지가 regex에 일치하는지 테스트합니다. regex는 정규식 객체나 re.search()에 사용되기 적합한 정규식 문자열이 될 수 있습니다. 예:

self.assertWarnsRegex(DeprecationWarning,
                      r'legacy_function\(\) is deprecated',
                      legacy_function, 'XYZ')

또는:

with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'):
    frobnicate('/etc/passwd')

버전 3.2에 추가.

버전 3.3에서 변경: 컨텍스트 관리자로 사용될 때 msg 키워드 인자 추가.

assertLogs(logger=None, level=None)

최소한 levellogger나 그 자식들에 최소한 1개의 메시지가 기록되는지 테스트하는 컨텍스트 관리자입니다.

logger가 주어졌다면, logging.Logger 객체이거나 로거의 이름인 str이어야 합니다. 기본값은 모든 메시지를 잡을 루트 로거입니다.

level이 주어졌다면, 로그 수준의 숫자 값이거나 그에 대응하는 문자열이어야 합니다(예를 들어 "ERROR"이거나 logging.ERROR). 기본값은 logging.INFO입니다.

만약 with 블록 안에서 loggerlevel 조건을 만족하는 최소한 1개의 메시지가 나왔다면 테스트는 성공하고, 그렇지 않으면 실패합니다.

컨텍스트 관리자에 의해 반환되는 객체는 조건에 일치하는 로그 메시지를 추적하기 위한 기록 도우미입니다. 이것은 2개의 어트리뷰트를 가지고 있습니다:

records

조건에 일치하는 메시지의 logging.LogRecord 객체 목록.

output

조건에 일치하는 메시지의 포맷 출력인 str 객체 목록.

예:

with self.assertLogs('foo', level='INFO') as cm:
   logging.getLogger('foo').info('first message')
   logging.getLogger('foo.bar').error('second message')
self.assertEqual(cm.output, ['INFO:foo:first message',
                             'ERROR:foo.bar:second message'])

버전 3.4에 추가.

더 구체적인 검사를 수행하기 위한 또 다른 메서드가 있습니다, 아래와 같이:

메서드

검사하는 내용

추가된 버전

assertAlmostEqual(a, b)

round(a-b, 7) == 0

assertNotAlmostEqual(a, b)

round(a-b, 7) != 0

assertGreater(a, b)

a > b

3.1

assertGreaterEqual(a, b)

a >= b

3.1

assertLess(a, b)

a < b

3.1

assertLessEqual(a, b)

a <= b

3.1

assertRegex(s, r)

r.search(s)

3.1

assertNotRegex(s, r)

not r.search(s)

3.2

assertCountEqual(a, b)

순서와 상관없이 ab가 같은 개수의 같은 요소를 가졌는지.

3.2

assertAlmostEqual(first, second, places=7, msg=None, delta=None)
assertNotAlmostEqual(first, second, places=7, msg=None, delta=None)

firstsecond가 근사하게 같은지(또는 근사하게 같지 않은지) 테스트합니다. 이는 값 차이를 계산하고, 주어진 소수 자릿(places)수(기본값 7)로 반올림한 뒤, 0과 비교하는 것으로 이루어집니다. 이 메서드는 값을 유효 숫자 자릿수(significant digits)가 아닌 주어진 소수 자릿수(decimal places)(즉, round() 함수와 같이)로 반올림합니다.

만약 places 대신에 delta가 주어진다면 firstsecond의 값 차이는 반드시 delta보다 작거나 같아야(또는 커야) 합니다.

deltaplaces가 동시에 주어지면 TypeError가 발생합니다.

버전 3.2에서 변경: assertAlmostEqual()은 같다고 비교되는 거의 동등한 객체를 자동으로 고려합니다. assertNotAlmostEqual()은 객체가 같다고 비교되면 자동으로 실패합니다. delta 키워드 인자를 추가.

assertGreater(first, second, msg=None)
assertGreaterEqual(first, second, msg=None)
assertLess(first, second, msg=None)
assertLessEqual(first, second, msg=None)

firstsecond와 비교해서 각각 메서드 이름에 해당하는 >, >=, <, <= 인지 테스트합니다. 그렇지 않으면 테스트는 실패합니다:

>>> self.assertGreaterEqual(3, 4)
AssertionError: "3" unexpectedly not greater than or equal to "4"

버전 3.1에 추가.

assertRegex(text, regex, msg=None)
assertNotRegex(text, regex, msg=None)

regex 검색이 text에 일치하는지(아닌지) 테스트합니다. 실패의 경우, 에러 메시지는 패턴과 text(또는 패턴과 예상과 달리 일치한 text의 부분)를 포함할 것입니다. regex는 정규식 객체나 re.search()에 사용되기 적합한 정규식 문자열이 될 수 있습니다.

버전 3.1에 추가: assertRegexpMatches 라는 이름으로 추가되었습니다.

버전 3.2에서 변경: assertRegexpMatches() 메서드가 assertRegex()로 이름 변경되었습니다.

버전 3.2에 추가: assertNotRegex().

버전 3.5에 추가: assertNotRegexpMatches이름은 assertNotRegex()의 폐지된 에일리어스입니다.

assertCountEqual(first, second, msg=None)

first 시퀀스가 순서에 상관없이 second와 같은 요소를 포함하는지 테스트합니다. 그렇지 않은 경우, 시퀀스들의 차이를 나열한 에러 메시지가 생성됩니다.

firstsecond를 비교할 때 중복된 요소는 무시하지 않습니다. 두 개의 시퀀스에 각 요소가 같은 수 만큼 있는 것을 확인합니다. assertEqual(Counter(list(first)), Counter(list(second)))와 같지만 해시 불가능한(unhashable) 시퀀스에도 작동합니다.

버전 3.2에 추가.

assertEqual() 메서드는 같은 형의 객체의 동등성 검사를 다른 형-특화 메서드에게로 보냅니다. 이러한 메서드들은 대부분의 내장 형에 대해서 이미 구현되어 있지만, addTypeEqualityFunc()을 사용하여 새로운 메서드를 등록하는 것도 가능합니다:

addTypeEqualityFunc(typeobj, function)

정확히 같은 (서브 클래스가 아닌) typeobj 형의 두 객체가 같은지 비교 검사하기 위해 assertEqual()한테 불리는 형-특화 메서드를 등록합니다. function은 반드시 2개의 위치 인자를 받아야 하고 assertEqual()이 그러한 것처럼 msg=None 키워드 인자를 세 번째로 받아야 합니다. 이것은 처음 2개의 매개변수가 같지 않은 것이 확인될 경우 self.failureException(msg)을 반드시 발생시켜야 합니다 – 에러 메시지에 유용한 정보를 제공하고 비동등성을 자세히 설명할 수 있을 것입니다.

버전 3.1에 추가.

assertEqual()에서 자동으로 사용하는 형-특화 메서드 목록은 다음 표에 정리되어 있습니다. 보통은 이 메서드를 직접 부를 필요가 없다는 것을 기억하십시오.

메서드

을 비교하기 위해

추가된 버전

assertMultiLineEqual(a, b)

문자열

3.1

assertSequenceEqual(a, b)

시퀀스

3.1

assertListEqual(a, b)

리스트

3.1

assertTupleEqual(a, b)

튜플

3.1

assertSetEqual(a, b)

집합 또는 불변 집합

3.1

assertDictEqual(a, b)

딕셔너리

3.1

assertMultiLineEqual(first, second, msg=None)

여러 줄 문자열인 firstsecond가 같은지 테스트합니다. 같지 않을 경우 에러 메시지에 다른 부분이 강조된 두 문자열의 차이가 포함됩니다. 이 메서드는 assertEqual()에서 문자열을 비교할 때 기본적으로 사용됩니다.

버전 3.1에 추가.

assertSequenceEqual(first, second, msg=None, seq_type=None)

2개의 시퀀스가 같은지 테스트합니다. seq_type이 전달된 경우, firstsecond 둘 다 seq_type의 인스턴스이어야 하고 그렇지 않은 경우 실패가 발생합니다. 시퀀스가 다른 경우, 에러 메시지는 2개 사이의 차이점을 보여주게 됩니다.

이 메서드는 assertEqual()에서 직접 호출되진 않지만, assertListEqual()assertTupleEqual()을 구현할 때 사용됩니다.

버전 3.1에 추가.

assertListEqual(first, second, msg=None)
assertTupleEqual(first, second, msg=None)

2개의 리스트나 튜플이 같은지 테스트합니다. 만약 같지 않다면 에러 메시지는 2개 사이의 차이점만 보여주게 됩니다. 매개변수 중 하나가 잘못된 형인 경우 에러가 발생합니다. 이 메서드는 assertEqual()에서 리스트와 튜플을 비교할 때 기본적으로 사용됩니다.

버전 3.1에 추가.

assertSetEqual(first, second, msg=None)

2개의 집합이 같은지 테스트합니다. 같지 않은 경우 에러 메시지는 집합 사이의 차이를 나열하게 됩니다. 이 메서드는 assertEqual()에서 집합이나 불변 집합을 비교할 때 기본적으로 사용됩니다.

firstsecond 중 하나가 set.difference() 메서드를 가지고 있지 않으면 실패합니다.

버전 3.1에 추가.

assertDictEqual(first, second, msg=None)

2개의 딕셔너리가 같은지 테스트합니다. 같지 않은 경우 에러 메시지는 딕셔너리 사이의 차이를 보여주게 됩니다. 이 메서드는 assertEqual()에서 딕셔너리를 비교할 때 기본적으로 사용될 것입니다.

버전 3.1에 추가.

마지막으로 TestCase가 다음의 메서드와 어트리뷰트를 제공합니다:

fail(msg=None)

무조건 테스트 실패 신호를 보냅니다, 에러 메시지를 위해 msgNone을 전달합니다.

failureException

이 클래스 어트리뷰트는 테스트 메서드에서 발생한 예외를 줍니다. 만약 테스트 프레임워크가 추가 정보를 전달하기 위해 특수한 예외를 사용할 필요가 있다면, 프레임워크와 “공정하게 행동하기” 위해서 이 예외를 서브 클래스해야 합니다. 이 어트리뷰트의 초깃값은 AssertionError 입니다.

longMessage

이 클래스 어트리뷰트는 실패한 assertXYY 호출에 msg 인자로 전달된 사용자 정의 실패 메시지가 어떻게 동작하는지를 결정합니다. True가 기본값입니다. 이 경우, 사용자 정의 메시지가 표준 실패 메시지 끝에 추가됩니다. False로 설정할 경우 사용자 정의 메시지가 표준 메시지를 대체합니다.

이 클래스 설정은 인스턴스 어트리뷰트를 설정하여 개별 테스트 메서드에 의해 재정의될 수 있습니다, assert 메서드를 호출하기 전에 self.longMessage를 True 또는 False로 설정하는 것입니다.

이 클래스 설정은 각 테스트 호출 전에 재설정됩니다.

버전 3.1에 추가.

maxDiff

이 어트리뷰트는 실패 시 diff를 보고하는 assert 메서드의 최대 diff 출력 길이를 설정합니다. 기본값은 80*8 문자입니다. 이 어트리뷰트에 영향을 받는 assert 메서드는 assertSequenceEqual()(이것에 위임하는 모든 시퀀스 비교 메서드를 포함), assertDictEqual(), assertMultiLineEqual() 입니다.

maxDiffNone으로 설정하면 diff의 최대 길이 제한이 없어지는 것을 뜻합니다.

버전 3.2에 추가.

테스트 프레임워크는 테스트에 관한 정보를 수집하기 위해 다음의 메서드를 사용할 수 있습니다:

countTestCases()

이 테스트 객체에 해당하는 테스트 개수를 반환합니다. TestCase 인스턴스에 대해서는 이것은 항상 1입니다.

defaultTestResult()

이 테스트 케이스 클래스를 위해서 사용되는 테스트 결과 클래스의 인스턴스를 반환합니다(run() 메서드에 다른 결과 인스턴스가 전달되지 않은 경우에).

TestCase 인스턴스에 대해서는 이것은 항상 TestResult의 인스턴스입니다; TestCase의 서브 클래스는 이것을 필요에 따라 재정의해야 합니다.

id()

특정 테스트 케이스를 식별하는 문자열을 반환합니다. 이것은 보통 모듈과 클래스 이름을 포함한 테스트 메서드의 완전한 이름(full name)입니다.

shortDescription()

테스트의 설명을 반환하거나 설명이 제공되지 않았으면 None을 반환합니다. 이 메서드의 기본 구현은 가능하다면 테스트 메서드의 독스트링의 첫 번째 줄을 반환하고 그렇지 않으면 None을 반환합니다.

버전 3.1에서 변경: 3.1 버전에서 docstring이 있는 경우에도 짧은 설명에 테스트 이름을 추가하도록 변경되었습니다. 이것은 unittest 확장과 호환성 문제를 일으켰고 테스트 이름 추가는 파이썬 3.2에서 TextTestResult로 옮겨졌습니다.

addCleanup(function, *args, **kwargs)

테스트 중에 사용된 자원을 정리하기 위해 tearDown() 이후에 불리는 함수를 추가합니다. 함수들은 추가된 순서의 반대 순서대로 불리게 됩니다(LIFO). 함수가 추가될 때 addCleanup()에 같이 전달된 위치 인자나 키워드 인자와 함께 호출됩니다.

만약 setUp()이 실패한다면, 즉 tearDown()이 불리지 않더라도, 정리 함수들은 여전히 불리게 될 것입니다.

버전 3.1에 추가.

doCleanups()

이 메서드는 tearDown() 이후나, setUp()이 예외를 발생시키면 setUp()이후에 조건 없이 호출됩니다.

addCleanup()에서 추가된 모든 정리 함수들을 호출하는 책임이 있습니다. 만약 정리 함수를 tearDown() 이전에 불러야 할 필요가 있다면 doCleanups()를 직접 부를 수 있습니다.

doCleanups()는 한 번에 하나씩 정리 함수 스택에서 메서드를 꺼내기 때문에 언제든지 호출될 수 있습니다.

버전 3.1에 추가.

class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)

이 클래스는 테스트 실행자가 테스트를 수행할 수 있게 TestCase 인터페이스 일부를 구현합니다, 하지만 테스트 코드가 검사하거나 에러를 보고하는 데 사용하는 메서드를 제공하지는 않습니다. 이것은 레거시 테스트 코드를 사용하여 테스트 케이스를 생성할 때 사용할 수 있습니다, 이것은 레거시 테스트 코드가 unittest-기반 테스트 프레임워크에 통합될 수 있게 해줍니다.

폐지된 에일리어스

역사적인 이유로 인해 TestCase 메서드의 일부는 지금은 폐지된 에일리어스를 1개 또는 그 이상 가졌습니다. 다음 표는 폐지된 에일리어스과 그에 맞는 올바른 이름을 나열합니다:

메서드 이름

폐지된 에일리어스

폐지된 에일리어스

assertEqual()

failUnlessEqual

assertEquals

assertNotEqual()

failIfEqual

assertNotEquals

assertTrue()

failUnless

assert_

assertFalse()

failIf

assertRaises()

failUnlessRaises

assertAlmostEqual()

failUnlessAlmostEqual

assertAlmostEquals

assertNotAlmostEqual()

failIfAlmostEqual

assertNotAlmostEquals

assertRegex()

assertRegexpMatches

assertNotRegex()

assertNotRegexpMatches

assertRaisesRegex()

assertRaisesRegexp

버전 3.1부터 폐지: 두 번째 열에 나열된 fail* 에일리어스는 폐지되었습니다.

버전 3.2부터 폐지: 세 번째 열에 나열된 assert* 에일리어스는 폐지되었습니다.

버전 3.2부터 폐지: assertRegexpMatchesassertRaisesRegexpassertRegex()assertRaisesRegex()로 이름이 변경되었습니다.

버전 3.5부터 폐지: assertNotRegexpMatches 이름은 폐지되고 assertNotRegex()으로 대체합니다.

테스트 분류

class unittest.TestSuite(tests=())

이 클래스는 개별 테스트 케이스와 테스트 묶음의 집합체를 나타냅니다. 이 클래스는 테스트 실행자가 이것을 다른 테스트 케이스처럼 실행할 수 있기 위해 필요한 인터페이스를 제공합니다. TestSuite 인스턴스를 실행하는 것은 테스트 묶음을 이터레이션하면서 각 테스트를 개별적으로 실행하는 것과 같습니다.

tests가 주어졌다면, 그것은 초기에 이 테스트 묶음을 만들 때 사용될 개별 테스트 케이스이거나 다른 테스트 묶음의 이터러블이어야 합니다. 나중에 컬렉션에 테스트 케이스나 테스트 묶음을 추가할 수 있는 추가 메서드가 제공됩니다.

TestSuite 객체는 TestCase 객체와 흡사하게 행동합니다만, 테스트를 실제로 구현하지 않는 것이 다릅니다. 대신에, 이것은 다 같이 실행되어야 하는 테스트 그룹에 테스트들을 모으는 데 사용됩니다. TestSuite 인스턴스에 테스트를 추가하기 위해 몇몇 추가적인 메서드를 사용할 수 있습니다.

addTest(test)

테스트 묶음에 TestCaseTestSuite 추가하기.

addTests(tests)

이 테스트 묶음에 TestCaseTestSuite 인스턴스의 이터러블에서 나온 모든 테스트를 추가하기.

이것은 tests를 이터레이션하면서 각 요소에 대해 addTest()를 호출하는 것과 같습니다.

TestSuite는 다음 메서드를 TestCase와 공유합니다:

run(result)

이 테스트 묶음과 연관된 테스트를 실행하고, result로 전달된 테스트 결과 객체에 결과를 수집합니다. TestCase.run()과 달리 TestSuite.run()은 결과 객체가 반드시 전달되어야 합니다.

debug()

결과를 수집하지 않고 이 테스트 묶음과 연관된 테스트를 실행합니다. 이것은 테스트에서 발생한 예외가 호출자로 전파될 수 있게 해서 디버거 환경에서 테스트를 실행할 때 사용될 수 있습니다.

countTestCases()

이 테스트 객체에 해당하는 테스트 개수를 반환합니다, 모든 개별 테스트와 서브-테스트 묶음을 포함합니다.

__iter__()

TestSuite로 묶인 테스트들은 항상 이터레이션으로 접근합니다. 서브 클래스는 __iter__()를 재정의하여 테스트를 지연해서 제공할 수 있습니다. 이 메서드는 한 개의 테스트 묶음에서 여러 번 불릴 수 있다는 것을 기억하십시오(예를 들어 테스트 개수를 세거나 동등성을 위해 비교할 때), 그러므로 TestSuite.run() 전에 수 번의 이터레이션이 반환한 테스트들은 매 이터레이션 호출마다 반드시 같아야 합니다. TestSuite.run() 후에는 호출자가 테스트 참조를 보존하기 위해 TestSuite._removeTestAtIndex()를 재정의한 서브 클래스를 사용하는 경우가 아니라면 이 메서드에 의해 반환된 테스트에 의존하면 안 됩니다.

버전 3.2에서 변경: 이전 버전에서는 TestSuite가 이터레이션을 사용하기보다는 직접 테스트에 접근했습니다, 따라서 __iter__()를 재정의하는 것은 테스트를 제공하기에 충분하지 않았습니다.

버전 3.4에서 변경: 이전 버전에서는 TestSuiteTestSuite.run() 후에 각 TestCase 의 참조를 유지했습니다. 서브 클래스는 TestSuite._removeTestAtIndex()를 재정의해서 이 동작을 복구할 수 있습니다.

TestSuite 객체의 전형적인 사용법은 최종 사용자 테스트 장치(harness)보다는 TestRunner에 의해 run() 메서드가 호출되는 것입니다.

테스트를 로드하고 실행하기

class unittest.TestLoader

TestLoader 클래스는 클래스와 모듈로부터 테스트 묶음을 생성하는 데 사용됩니다. 보통, 이 클래스의 인스턴스를 생성할 필요는 없습니다; unittest 모듈은 공유 가능한 unittest.defaultTestLoader 인스턴스를 제공합니다. 그러나 서브 클래스나 인스턴스를 사용함으로 몇몇 변경 가능한 속성을 사용자 정의할 수 있습니다.

TestLoader 객체는 다음 어트리뷰트를 가집니다:

errors

테스트를 로드하는 동안 발생한 치명적이지 않은(non-fatal) 에러 목록입니다. 어떤 시점에도 로더에 의해 재설정되지 않습니다. 치명적인 에러는 예외를 발생시키는 관련 메서드에 의해 신호가 발생하여 호출자에게 전달됩니다. 치명적이지 않은 에러는 실행 시에 원래 에러를 발생시킬 합성(synthetic) 테스트가 표시하기도 합니다.

버전 3.5에 추가.

TestLoader 객체는 다음 메서드를 가집니다:

loadTestsFromTestCase(testCaseClass)

TestCase에서 파생된 testCaseClass에 포함된 모든 테스트 케이스의 묶음을 반환합니다.

테스트 케이스 인스턴스는 getTestCaseNames()에 의해 이름 지어진 각 메서드를 위해 생성됩니다. 기본값은 test로 시작되는 메서드 이름입니다. 만약 getTestCaseNames()가 아무 메서드도 반환하지 않지만, runTest() 메서드가 구현되었다면 이 메서드를 위해서 1개의 테스트 케이스가 대신 생성됩니다.

loadTestsFromModule(module, pattern=None)

주어진 모듈에 포함된 모든 테스트 케이스 묶음을 반환합니다. 이 메서드는 TestCase에서 파생된 클래스를 찾기 위해 module을 검색하고 클래스에 정의된 각 테스트 메서드를 위해 클래스의 인스턴스를 생성합니다.

참고

TestCase에서 파생된 클래스의 계층 사용이 픽스쳐와 도우미 함수를 공유하는 데 편리할 수 있지만 직접 인스턴스화를 하도록 의도되지 않은 베이스 클래스에 테스트 메서드를 정의하는 것은 이 메서드와 잘 작동하지 않습니다. 그러나 그렇게 하는 것이 픽스처들이 다르고 서브 클래스에서 정의될 경우에는 유용할 수 있습니다.

만약 모듈이 load_tests 함수를 제공한다면 테스트 로드를 위해 이것을 호출할 것입니다. 이것은 모듈이 테스트 로드를 사용자 정의할 수 있도록 해줍니다. 이것은 load_tests 프로토콜입니다. pattern 인자는 load_tests에 세 번째 인자로 전달됩니다.

버전 3.2에서 변경: load_tests 지원이 추가됨.

버전 3.5에서 변경: 문서로 만들어 져 있지 않고 공식적이지 않은 use_load_tests 기본 인자를 폐지하고 무시합니다, 하지만 하위 호환성을 위해 여전히 그것을 수용합니다. 이 메서드는 이제 load_tests에 세 번째 인자로 전달되는 pattern을 오직 키워드 인자로써 수용합니다.

loadTestsFromName(name, module=None)

문자열 지정자에 맞는 모든 테스트 케이스 묶음을 반환합니다.

지정자 name은 모듈, 테스트 케이스 클래스, 테스트 케이스 클래스에 있는 테스트 메서드, TestSuite 인스턴스, TestCaseTestSuite 인스턴스를 반환하는 콜러블 객체로 해석될 수 있는 “점으로 구분된 이름(dotted name)”입니다. 이 검사는 여기에 나열된 순서대로 적용됩니다; 즉, 테스트 케이스 클래스에 있는 메서드는 “콜러블 객체”보다는 “테스트 케이스 클래스에 있는 테스트 메서드”로 선택될 것입니다.

예를 들어, 만약 당신이 TestCase에서 파생된 클래스인 SampleTestCase를 포함한 SampleTests 모듈을 가지고 있고 그 클래스는 3개의 테스트 메서드(test_one(), test_two(), test_three())를 가지고 있다면, 지정자 'SampleTests.SampleTestCase' 에 대해서 이 메서드는 모든 3개의 테스트 메서드를 실행할 테스트 묶음으로 반환할 것입니다. 지정자가 'SampleTests.SampleTestCase.test_two' 라면 이 메서드는 오직 test_two() 테스트 메서드를 실행할 테스트 묶음을 반환할 것입니다. 지정자는 아직 임포트되지 않은 모듈이나 패키지를 가리킬 수 있습니다; 부작용(side-effect)으로써 그것들이 임포트될 것입니다.

이 메서드는 주어진 module에 상대적인 name을 선택적으로 해석할 수 있습니다.

버전 3.5에서 변경: 만약 name 순회 중에 ImportErrorAttributeError가 발생한다면 실행할 때 그 에러를 일으키는 합성 테스트가 반환될 것입니다. 이 에러는 self.errors 에러 모임에 포함될 것입니다.

loadTestsFromNames(names, module=None)

loadTestsFromName()와 비슷하지만, 1개의 이름이 아닌 이름의 시퀀스를 받습니다. 반환 값은 각 이름에 정의된 모든 테스트를 지원하는 테스트 묶음입니다.

getTestCaseNames(testCaseClass)

testCaseClass 안에서 찾은 메서드 이름을 정렬된 시퀀스로 반환합니다; 이 클래스는 TestCase의 서브 클래스이어야 합니다.

discover(start_dir, pattern='test*.py', top_level_dir=None)

지정된 시작 디렉터리부터 하위 디렉터리를 재귀적으로 순회하여 모든 테스트 모듈을 찾아, 이를 포함하는 TestSuite 객체를 반환합니다. pattern에 일치하는 테스트 파일만 로드될 것입니다. (셸 방식의 패턴 일치를 사용합니다.) 임포트 가능한(즉, 유효한 파이썬 식별자인) 모듈 이름만 로드될 것입니다.

모든 테스트 모듈은 반드시 프로젝트의 최상위 수준에서 임포트 가능해야 합니다. 만약 시작 디렉터리가 최상위 디렉터리가 아니라면 최상위 디렉터리를 따로 지정해야 합니다.

만약 모듈 임포트가 실패한다면, 예를 들어 문법 에러로 인해, 이것은 1개의 에러로 기록되고 탐색이 계속 진행될 것입니다. 만약 SkipTest가 발생해서 임포트가 실패했다면, 이것은 에러가 아닌 건너뛰기로 기록될 것입니다.

만약 패키지(__init__.py 라는 이름의 파일을 포함한 디렉터리)를 찾으면, load_tests 함수가 있는지 패키지를 검사할 것입니다. 만약 존재한다면 그 패키지에 대해서 package.load_tests(loader, tests, pattern)가 불릴 것입니다. 만약 load_tests 함수 자체가 loader.discover를 호출할지라도, 테스트 탐색은 실행 중에 패키지에 대한 테스트 검사를 한 번만 실행하도록 보장합니다.

만약 load_tests가 존재한다면 탐색은 패키지 안을 재귀 탐색하지 않습니다. load_tests가 패키지 안의 모든 테스트를 로드할 책임이 있습니다.

패턴은 의도적으로 로더 어트리뷰트로 저장되지 않아 패키지가 자신에 대한 탐색을 계속할 수 있습니다. top_level_dir는 저장되어 load_testsloader.discover()에게 이 인자를 건네줄 필요가 없습니다.

start_dir는 디렉터리뿐만 아니라 점으로 구분된 모듈 이름이 될 수 있습니다.

버전 3.2에 추가.

버전 3.4에서 변경: 임포트 시에 SkipTest가 발생한 모듈은 에러가 아닌, 건너뛰기로 기록됩니다. 탐색은 이름 공간 패키지를 지원합니다. 임포트되기 전에 경로들이 정렬되어 파일 시스템의 정렬 순서가 파일 이름에 의존하지 않더라도 실행 순서가 같아지도록 합니다.

버전 3.5에서 변경: 이제 발견된 패키지는 그것의 경로가 pattern과 일치하는지 여부와 상관없이 load_tests를 검사합니다, 왜냐하면 패키지 이름이 기본 패턴과 일치하는 것이 불가능하기 때문입니다.

TestLoader의 다음 어트리뷰트들은 서브 클래스나 인스턴스에 대입을 통해 구성할 수 있습니다.

testMethodPrefix

테스트 메서드로 해석할 메서드 이름의 접두사에 해당하는 문자열입니다. 기본값은 'test' 입니다.

이것은 getTestCaseNames() 과 모든 loadTestsFrom*() 메서드에 영향을 미칩니다.

sortTestMethodsUsing

getTestCaseNames()와 모든 loadTestsFrom*() 메서드에서 메서드 이름 정렬 시에 이름 비교하는 데 사용될 함수입니다.

suiteClass

테스트 목록에서 테스트 묶음을 생성하는 콜러블 객체입니다. 결과 객체에 어떤 메서드도 필요하지 않습니다. 기본값은 TestSuite 클래스입니다.

이것은 모든 loadTestsFrom*() 메서드에 영향을 미칩니다.

testNamePatterns

테스트 묶음에 포함되기 위해서 테스트 메서드가 일치해야 할 유닉스 셸-방식의 와일드카드 테스트 이름 패턴 목록입니다(-v 옵션을 보십시오).

만약 이 어트리뷰트가 None(기본값)이 아니라면, 테스트 묶음에 포함될 모든 테스트 메서드는 이 목록의 패턴 중 1개와 반드시 일치해야 합니다. 이 패턴 일치는 항상 fnmatch.fnmatchcase()를 사용하여 수행된다는 것을 기억하십시오, 그래서 -v 옵션에 패턴을 건네주는 것과 달리, 간단한 부분 문자열 패턴은 * 와일드카드를 사용하도록 변경되어야 할 것입니다.

이것은 모든 loadTestsFrom*() 메서드에 영향을 미칩니다.

버전 3.7에 추가.

class unittest.TestResult

어떤 테스트가 성공했고 어떤 테스트가 실패했는지에 관한 정보를 엮는데 사용되는 클래스입니다.

TestResult 객체는 여러 테스트의 결과들을 저장합니다. TestCaseTestSuite 클래스는 결과가 올바르게 기록되는 것을 보장합니다; 테스트 작성자가 테스트 결과를 기록하는 것에 대해서 걱정할 필요가 없습니다.

unittest 위에 만들어진 테스트 프레임워크는 보고 목적으로 여러 테스트가 실행하면서 만들어낸 TestResult 객체에 접근하고 싶을 수도 있습니다; TestRunner.run() 메서드는 이 목적을 위해 TestResult 인스턴스를 반환합니다.

TestResult 인스턴스는 테스트 실행 결과를 조사할 때 관심이 생길만한 다음과 같은 어트리뷰트를 가지고 있습니다.

errors

TestCase 인스턴스와 포맷된(formatted) 트레이스백 문자열로 구성된 2-튜플을 포함하는 목록입니다. 각 튜플은 예기치 못한 예외가 발생한 테스트에 해당합니다.

failures

TestCase 인스턴스와 포맷된(formatted) 트레이스백 문자열로 구성된 2-튜플을 포함하는 목록입니다. 각 튜플은 TestCase.assert*() 메서드를 사용하여 명시적으로 실패가 발생한 테스트에 해당합니다.

skipped

TestCase 인스턴스와 테스트 건너뛰기한 이유 문자열로 구성된 2-튜플을 포함하는 목록입니다.

버전 3.1에 추가.

expectedFailures

TestCase 인스턴스와 포맷된(formatted) 트레이스백 문자열로 구성된 2-튜플을 포함하는 목록입니다. 각 튜플은 테스트 케이스의 예상된 실패에 해당합니다.

unexpectedSuccesses

예상된 실패로 표시되었지만 성공한 TestCase 인스턴스를 포함하는 목록입니다.

shouldStop

테스트 실행이 stop()에 의해 정지되어야 할 때 True로 설정합니다.

testsRun

이제까지 실행된 테스트 총 개수입니다.

buffer

참으로 설정하면 sys.stdoutsys.stderrstartTest()stopTest() 호출 사이에서 버퍼링될 것입니다. 수집된 출력은 테스트가 실패하거나 에러가 발생한 경우에만 실제 sys.stdoutsys.stderr에 출력될 것입니다. 모든 출력은 실패 / 에러 메시지에도 첨부됩니다.

버전 3.2에 추가.

failfast

참으로 설정하면 첫 번째 실패 또는 에러에서 stop()이 호출될 것입니다.

버전 3.2에 추가.

tb_locals

참으로 설정하면 지역 변수가 트레이스백에 보일 것입니다.

버전 3.5에 추가.

wasSuccessful()

이제까지 실행한 모든 테스트가 성공했다면 True를 반환하고, 그렇지 않으면 False를 반환합니다.

버전 3.4에서 변경: expectedFailure() 데코레이터로 표시된 테스트에서 unexpectedSuccesses가 있다면 False를 반환합니다.

stop()

shouldStop 어트리뷰트를 True로 설정하여 현재 실행 중인 테스트 모음을 중단해야 함을 알리기 위한 용도로 이 메서드를 부를 수 있습니다. TestRunner 객체는 이 신호를 존중하여 어떠한 추가 테스트 없이 반환해야 합니다.

예를 들어, 사용자가 키보드로 중단 신호를 보낼 때 테스트 프레임워크를 중단하기 위해 TextTestRunner가 이 기능을 사용합니다. TestRunner 구현을 제공하는 대화형 도구는 비슷한 방법으로 이것을 사용할 수 있습니다.

TestResult 클래스의 다음 메서드는 내부 자료 구조를 관리하려고 사용되고, 추가적인 보고 요구사항을 지원하기 위해 서브 클래스에서 확장할 수도 있습니다. 이것은 테스트가 실행 중에 대화형 보고를 지원하는 도구를 만들 때 특별히 유용합니다.

startTest(test)

테스트 케이스 test가 막 실행되려 할 때 호출됩니다.

stopTest(test)

결과에 상관없이 테스트 케이스 test가 실행되고 나서 호출됩니다.

startTestRun()

모든 테스트가 실행되기 전에 1번 호출됩니다.

버전 3.1에 추가.

stopTestRun()

모든 테스트가 실행되고 나서 1번 호출됩니다.

버전 3.1에 추가.

addError(test, err)

테스트 케이스 test가 예기치 못한 예외를 발생한 경우 호출됩니다. errsys.exc_info()가 반환한 형식의 튜플입니다: (type, value, traceback).

기본 구현은 (test, formatted_err) 튜플을 인스턴스의 errors 어트리뷰트에 추가합니다, 여기서 formatted_errerr에서 파생된 포맷한 트레이스백입니다.

addFailure(test, err)

테스트 케이스 test가 실패 신호를 보낸 경우 호출됩니다. errsys.exc_info()가 반환한 형식의 튜플입니다: (type, value, traceback).

기본 구현은 (test, formatted_err) 튜플을 인스턴스의 failures 어트리뷰트에 추가합니다, 여기서 formatted_errerr에서 파생된 포맷한 트레이스백입니다.

addSuccess(test)

테스트 케이스 test가 성공하면 호출됩니다.

기본 구현은 아무것도 하지 않습니다.

addSkip(test, reason)

테스트 케이스 test가 건너뛰어지면 호출됩니다. reason은 테스트가 준 건너뛰는 이유입니다.

기본 구현은 (test, reason) 튜플을 인스턴스의 skipped 어트리뷰트에 추가합니다.

addExpectedFailure(test, err)

테스트 케이스 test가 실패했지만 expectedFailure() 데코레이터로 표시된 경우 호출됩니다

기본 구현은 (test, formatted_err) 튜플을 인스턴스의 expectedFailures 어트리뷰트에 추가합니다, 여기서 formatted_errerr에서 파생된 포맷한 트레이스백입니다.

addUnexpectedSuccess(test)

테스트 케이스 testexpectedFailure() 데코레이터로 표시되었지만, 성공한 경우 호출됩니다.

기본 구현은 테스트를 인스턴스의 unexpectedSuccesses 어트리뷰트에 추가합니다.

addSubTest(test, subtest, outcome)

부분 테스트가 완료되었을 때 호출됩니다. test는 테스트 메서드에 대응하는 테스트 케이스입니다. subtest는 부분 테스트를 설명하는 사용자 지정 TestCase 인스턴스입니다.

outcomeNone이면, 부분 테스트가 성공한 것입니다. 그렇지 않으면 예외와 함께 실패한 것인데 outcomesys.exc_info()가 반환한 형식의 튜플입니다: (type, value, traceback).

기본 구현은 결과가 성공인 경우 아무것도 하지 않고 부분 테스트의 실패를 일반적인 실패로 기록합니다.

버전 3.4에 추가.

class unittest.TextTestResult(stream, descriptions, verbosity)

TextTestRunner에서 사용하는 TestResult의 구체적인 구현입니다.

버전 3.2에 추가: 이 클래스는 이전에 _TextTestResult 이름이었습니다. 이 이름은 여전히 에일리어스로 존재하지만 폐지된 상태입니다.

unittest.defaultTestLoader

공유 목적의 TestLoader 클래스의 인스턴스입니다. 만약 TestLoader를 사용자 정의할 필요가 없다면, 계속 새로운 인스턴스를 생성하는 것 대신 이 인스턴스를 사용할 수 있습니다.

class unittest.TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, *, tb_locals=False)

결과를 스트림으로 출력하는 기본 테스트 실행자 구현입니다. 만약 stream이 기본값인 None이라면, sys.stderr가 출력 스트림으로 사용됩니다. 이 클래스는 몇 가지 설정 가능한 매개변수를 가지고 있지만, 본질적으로 매우 간단합니다. 테스트 묶음을 실행하는 그래픽 애플리케이션은 대안 구현을 제공해야 합니다. 이러한 구현은 unittest에 기능이 추가될 때 실행자를 만드는 인터페이스가 변하기 때문에 **kwargs를 받아들여야 합니다.

기본적으로 이 실행자는 DeprecationWarning, PendingDeprecationWarning, ResourceWarning, ImportWarning기본적으로 무시 설정이 되어 있더라도 이것들을 보여줍니다. 폐지된 unittest 메서드 에 의해 발생한 폐지 경고도 특수한 경우이고, 경고 필터가 'default' 또는 'always' 일 때, 너무 많은 경고 메시지를 피하고자 그것들이 모듈당 1번만 보일 것입니다. 파이썬의 -Wd이나 -Wa 옵션(경고 제어를 보십시오)을 사용하고 warningsNone으로 설정하여 이 동작을 오버라이드 할 수 있습니다.

버전 3.2에서 변경: warnings 인자 추가.

버전 3.2에서 변경: 임포트 시간이 아닌 인스턴스화 시간에 기본 스트림이 sys.stderr으로 설정됩니다.

버전 3.5에서 변경: tb_locals 매개변수 추가.

_makeResult()

이 메서드는 run()가 사용하는 TestResult 인스턴스를 반환합니다. 직접 호출하게 의도되지 않았지만, 사용자 정의 TestResult를 제공하기 위해 서브 클래스에서 오버라이드할 수 있습니다.

_makeResult()TextTestRunner 생성자에 resultclass 인자로 전달된 클래스나 콜러블을 인스턴스화합니다. 만약 resultclass가 제공되지 않았다면 기본값은 TextTestResult 입니다. 결과 클래스는 다음 인자와 함께 인스턴스화됩니다:

stream, descriptions, verbosity
run(test)

이 메서드는 TextTestRunner의 주된 공개 인터페이스입니다. 이 메서드는 TestSuiteTestCase 인스턴스를 받습니다. TestResult_makeResult()를 호출하여 생성하고 테스트가 실행되며 결과가 stdout에 출력됩니다.

unittest.main(module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=unittest.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None, warnings=None)

module에서 테스트 모음을 로드하고 실행하는 명령행 프로그램입니다; 이것은 주로 편리하게 실행 가능한 테스트 모듈을 만들기 위한 것입니다. 이 함수의 가장 간단한 사용은 테스트 스크립트 마지막에 다음과 같은 줄을 포함하는 것입니다:

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

당신은 상세도 인자를 전달하여 좀 더 자세한 정보와 함께 테스트를 실행할 수 있습니다:

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

defaultTest 인자는 argv로 테스트 이름이 지정되지 않은 경우 실행될 1개의 테스트 이름이거나 테스트 이름의 이터러블입니다. 만약 이 인자가 지정되지 않거나 None이면서 argv로 테스트 이름이 지정되지 않으면 module 안에서 찾은 모든 테스트가 실행됩니다.

argv 인자는 프로그램에 전달된 옵션 목록이 될 수 있습니다, 첫 번째 요소는 프로그램 이름입니다. 만약 이 인자가 지정되지 않거나 None이면, sys.argv 값이 사용됩니다.

testRunner 인자는 테스트 실행자 클래스나 이미 생성된 테스트 실행자 인스턴스일 수 있습니다. 기본적으로 main은 실행한 테스트가 성공인지 실패인지를 나타내는 종료 코드와 함께 sys.exit()을 호출합니다.

testLoader 인자는 TestLoader 인스턴스이어야 하고 기본값은 defaultTestLoader 입니다.

mainexit=False 인자를 전달하여 대화형 인터프리터에서 사용하는 것을 지원합니다. 이것은 sys.exit() 호출 없이 결과가 표준 출력에 표시됩니다:

>>> from unittest import main
>>> main(module='test_module', exit=False)

failfast, catchbreak, buffer 매개변수는 명령행 옵션의 같은 이름과 같은 효과를 가지고 있습니다.

warnings 인자는 테스트 실행 중에 사용되어야 할 경고 필터를 지정합니다. 만약 아무 값도 지정되지 않았다면, -W 옵션이 python으로 전달된 경우(경고 제어를 보십시오)에는 None으로 남아 있고, 그렇지 않은 경우에는 'default'로 설정됩니다.

사실 main 호출은 TestProgram 클래스의 인스턴스를 반환합니다. 이것은 실행된 테스트의 결과를 result 어트리뷰트에 저장합니다.

버전 3.1에서 변경: exit 매개변수가 추가되었습니다.

버전 3.2에서 변경: verbosity, failfast, catchbreak, buffer, warnings 매개변수가 추가되었습니다.

버전 3.4에서 변경: defaultTest 매개변수가 테스트 이름의 이터러블도 받을 수 있게 바뀌었습니다.

load_tests 프로토콜

버전 3.2에 추가.

load_tests 라 불리는 함수를 구현함으로써 모듈이나 패키지는 일반 테스트 실행이나 테스트 탐색 중에 그것들로부터 테스트가 어떻게 로드될지를 사용자 정의할 수 있습니다.

만약 테스트 모듈이 load_tests를 정의했다면 그것은 다음 인자와 함께 TestLoader.loadTestsFromModule()의해 호출될 것입니다:

load_tests(loader, standard_tests, pattern)

여기서 patternloadTestsFromModule에서 바로 전달된 것입니다. 기본값은 None입니다.

이것은 TestSuite를 반환해야 합니다.

loader는 로딩을 실행할 TestLoader 인스턴스입니다. standard_tests는 모듈에서 기본적으로 로드될 테스트입니다. 테스트 모듈이 테스트 기본 모음에서 오직 테스트를 추가하거나 빼기를 원하는 것은 흔한 일입니다. 세 번째 인자는 테스트 탐색의 일부로서 패키지를 로드할 때 사용됩니다.

특정 TestCase 클래스 모음에서 테스트를 로드하는 전형적인 load_tests 함수는 다음과 같습니다:

test_cases = (TestCase1, TestCase2, TestCase3)

def load_tests(loader, tests, pattern):
    suite = TestSuite()
    for test_class in test_cases:
        tests = loader.loadTestsFromTestCase(test_class)
        suite.addTests(tests)
    return suite

만약 탐색이 명령행 또는 TestLoader.discover()로부터, 패키지가 포함된 디렉터리에서 시작된다면, load_tests를 위해 패키지 __init__.py를 검사합니다. 만약 함수가 존재하지 않으면, 탐색은 그저 다른 디렉터리인 것처럼 패키지 안을 재귀 순회할 것입니다. 그렇지 않다면, 패키지의 테스트를 위한 탐색은 다음 인자와 함께 불리는 load_tests에게 맡겨질 것입니다:

load_tests(loader, standard_tests, pattern)

이것은 패키지의 모든 테스트에 해당하는 TestSuite를 반환해야 합니다. (standard_tests는 오직 __init__.py로부터 수집된 테스트만 포함할 것입니다.

패턴이 load_tests로 전달되기 때문에 패키지는 테스트 검색을 계속 진행(그리고 잠재적으로 수정)할 수 있습니다. 테스트 패키지를 위해서 ‘아무것도 하지 않는’ load_tests 함수는 다음과 같을 것입니다:

def load_tests(loader, standard_tests, pattern):
    # top level directory cached on loader instance
    this_dir = os.path.dirname(__file__)
    package_tests = loader.discover(start_dir=this_dir, pattern=pattern)
    standard_tests.addTests(package_tests)
    return standard_tests

버전 3.5에서 변경: 패키지 이름이 기본 패턴과 일치하는 것이 불가능하기 때문에 탐색이 더는 pattern 일치를 위해서 패키지 이름을 검사하지 않습니다.

클래스와 모듈 픽스쳐

클래스와 모듈 단계의 픽스쳐는 TestSuite에 구현되어 있습니다. 테스트 묶음이 새로운 클래스의 테스트를 만나면(만약 존재한다면) 이전 클래스의 tearDownClass() 가 호출되고, 이어 새로운 클래스의 setUpClass()가 호출됩니다.

마찬가지로 만약 테스트가 이전 테스트와 다른 모듈의 것이라면 이전 모듈의 tearDownModule이 실행되고, 이어 새로운 모듈의 setUpModule이 호출됩니다.

모든 테스트가 실행된 뒤에 마지막으로 tearDownClasstearDownModule이 실행됩니다.

공유하는 픽스쳐의 경우 테스트 병렬화와 같은 [잠재적인] 기능과 잘 동작하지 않고 이것은 테스트 분리를 망가트립니다. 이것을 주의 깊게 사용해야 합니다.

unittest의 테스트 로더에 의해 생성된 테스트들의 기본 정렬 순서는 같은 모듈과 클래스의 모든 테스트를 그룹화하는 것입니다. 이것은 setUpClass / setUpModule(등) 이 클래스와 모듈별로 정확하게 1번씩 호출되게 할 것입니다. 만약 당신이 무작위로 순서를 정하여, 그래서 다른 모듈과 클래스의 테스트가 서로 인접한다면, 이 공유 픽스처 함수는 1번의 테스트 실행에서 여러 번 호출될 수 있습니다.

공유 픽스처는 비표준 정렬 순서를 사용하는 테스트 묶음과 같이 작동하는 것을 의도하지 않습니다. 공유 픽스처를 지원하길 원치 않는 프레임워크를 위해서 BaseTestSuite가 여전히 존재합니다.

공유 픽스처 함수 중 1개에서 발생한 예외가 있다면, 테스트를 에러로 보고합니다. 해당 테스트 인스턴스가 없기 때문에 에러를 나타내기 위해 _ErrorHolder 객체(TestCase와 같은 인터페이스를 가진)가 생성됩니다. 당신이 그저 표준 unittest의 테스트 실행자를 사용한다면 이 세부 항목은 중요하지 않습니다, 그러나 당신이 프레임워크의 저자라면 이것은 관련이 있을 수 있습니다.

setUpClass 와 tearDownClass

이것들은 반드시 클래스 메서드로 구현되어야 합니다:

import unittest

class Test(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._connection = createExpensiveConnectionObject()

    @classmethod
    def tearDownClass(cls):
        cls._connection.destroy()

만약 당신이 베이스 클래스의 setUpClasstearDownClass를 호출하고 싶다면 당신이 그것을 직접 호출해야만 합니다. TestCase의 구현은 비어있습니다.

만약 setUpClass 중에 예외가 발생한다면 클래스의 테스트는 실행되지 않고 tearDownClass 는 실행되지 않습니다. 건너뛴 클래스는 setUpClass 또는 tearDownClass가 실행되지 않을 것입니다. 만약 예외가 SkipTest 예외라면 클래스는 에러 대신 건너뛰어졌다고 보고될 것입니다.

setUpModule 과 tearDownModule

이것들은 함수로 구현되어야 합니다:

def setUpModule():
    createConnection()

def tearDownModule():
    closeConnection()

만약 setUpModule 중에 예외가 발생한다면 모듈의 테스트는 실행되지 않고 tearDownModule 는 실행되지 않습니다. 만약 예외가 SkipTest 예외라면 모듈은 에러 대신 건너뛰어졌다고 보고될 것입니다.

시그널 처리하기

버전 3.2에 추가.

unittest의 -c/--catch 명령행 옵션은, unittest.main()catchbreak 매개 변수와 함께, 테스트 실행 중에 control-C를 사용하기 편하게 처리하도록 합니다. 중단 시그널 잡기를 활성화 하면 control-C는 현재 실행 중인 테스트를 완료하고, 그러면 테스트 실행이 끝나고 이제까지의 모든 결과를 보고할 것입니다. 두 번째 control-c는 평소와 같이 KeyboardInterrupt를 발생할 것입니다.

control-c 시그널 처리기는 자체 signal.SIGINT 처리기를 설치하는 코드 또는 테스트와의 호환성을 유지하려고 노력합니다. 만약 unittest 처리기가 불리지만 그것이 설치된 signal.SIGINT 처리기가 아니면, 즉 그것이 테스트 중에 시스템에 의해 대체되고 위임된다면, 그것은 기본 처리기를 호출합니다. 이것은 설치된 처리기를 대체하고 위임하는 코드에 의해 일반적으로 기대되는 동작입니다. unittest control-c 처리를 개별 테스트 별로 비활성화하고 싶을 때는 removeHandler() 데코레이터를 사용할 수 있습니다.

프레임워크 작성자가 테스트 프레임워크에서 control-c 처리 기능을 활성화하기 위해 몇 가지 유틸리티 함수가 있습니다.

unittest.installHandler()

control-c 처리기를 설치합니다. signal.SIGINT를 받았을 때(보통 사용자가 control-c를 눌렀을 때의 응답으로써) 모든 등록된 결과에 stop()이 호출됩니다.

unittest.registerResult(result)

control-c 처리를 위해서 TestResult 객체를 등록합니다. 결과 등록은 그것의 약한 참조를 저장합니다, 그래서 결과가 가비지 수거되는 것을 막지 않습니다.

만약 control-c 처리가 활성화되지 않았다면 TestResult 객체 등록은 부작용이 없습니다, 그래서 테스트 프레임워크는 처리가 가능한지 여부와 관계없이 자신이 만든 모든 결과를 무조건 등록할 수 있습니다.

unittest.removeResult(result)

등록한 결과를 제거합니다. 결과가 제거되고 나면 control-c에 대한 응답으로 결과 객체의 stop()을 더는 호출하지 않게 됩니다.

unittest.removeHandler(function=None)

인자 없이 호출된 경우 이 함수는 만약 control-c 처리기가 설치되었다면 그것을 제거합니다. 또한 이 함수는 테스트 실행 중에 임시로 처리기를 제거하기 위해 테스트 데코레이터로써 사용될 수도 있습니다:

@unittest.removeHandler
def test_signal_handling(self):
    ...