doctest --- 대화형 파이썬 예제 테스트

소스 코드: Lib/doctest.py


doctest 모듈은 대화형 파이썬 세션처럼 보이는 텍스트를 검색한 다음, 해당 세션을 실행하여 표시된 대로 정확하게 작동하는지 검증합니다. doctest를 사용하는 몇 가지 일반적인 방법이 있습니다:

  • 모든 대화식 예제가 설명된 대로 작동하는지 확인하여 모듈의 독스트링이 최신인지 확인합니다.

  • 테스트 파일이나 테스트 객체의 대화형 예제가 예상대로 작동하는지 확인하여 회귀 테스트를 수행합니다.

  • 입/출력 예제를 그대로 보여줌으로써 패키지에 대한 자습서를 작성합니다. 예제나 설명문 중 어느 것이 강조되는지에 따라, "문학적 테스트(literate testing)"나 "실행 가능한 설명서(executable documentation)"의 느낌을 줍니다.

여기에 완전하지만 작은 예제 모듈이 있습니다:

"""
이것은 "예제" 모듈입니다.

예제 모듈은 factorial() 함수 하나를 제공합니다. 예를 들어,

>>> factorial(5)
120
"""

def factorial(n):
    """n의 계승을 반환합니다, 정확한 정수 >= 0.

    >>> [factorial(n) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    >>> factorial(30)
    265252859812191058636308480000000
    >>> factorial(-1)
    Traceback (most recent call last):
        ...
    ValueError: n must be >= 0

    float의 계승도 좋습니다만, float는 정확한 정수여야 합니다:
    >>> factorial(30.1)
    Traceback (most recent call last):
        ...
    ValueError: n must be exact integer
    >>> factorial(30.0)
    265252859812191058636308480000000

    또한 터무니없이 크지 않아야 합니다:
    >>> factorial(1e100)
    Traceback (most recent call last):
        ...
    OverflowError: n too large
    """

    import math
    if not n >= 0:
        raise ValueError("n must be >= 0")
    if math.floor(n) != n:
        raise ValueError("n must be exact integer")
    if n+1 == n:  # 1e300과 같은 값을 잡아냅니다
        raise OverflowError("n too large")
    result = 1
    factor = 2
    while factor <= n:
        result *= factor
        factor += 1
    return result


if __name__ == "__main__":
    import doctest
    doctest.testmod()

example.py를 명령 줄에서 직접 실행하면, doctest가 마술을 부리기 시작합니다:

$ python example.py
$

출력이 없습니다! 이것이 정상이며, 모든 예제가 작동했다는 것을 뜻합니다. -v를 스크립트에 전달하면, doctest는 시도하고 있는 내용에 대한 자세한 로그를 출력하고 끝에 요약을 인쇄합니다.:

$ python example.py -v
Trying:
    factorial(5)
Expecting:
    120
ok
Trying:
    [factorial(n) for n in range(6)]
Expecting:
    [1, 1, 2, 6, 24, 120]
ok

결국, 다음과 같이 끝납니다:

Trying:
    factorial(1e100)
Expecting:
    Traceback (most recent call last):
        ...
    OverflowError: n too large
ok
2 items passed all tests:
   1 tests in __main__
   8 tests in __main__.factorial
9 tests in 2 items.
9 passed and 0 failed.
Test passed.
$

이것이 doctest를 생산적으로 사용하기 위해서 알아야 할 모든 것입니다! 시도해 보세요. 다음 절에서는 자세한 내용을 제공합니다. 표준 파이썬 테스트 스위트와 라이브러리에는 doctest 예제가 많습니다. 특히 유용한 예제는 표준 테스트 파일 Lib/test/test_doctest.py에서 찾을 수 있습니다.

간단한 사용법: 독스트링에 있는 예제 확인하기

doctest를 사용하는 가장 간단한 방법은 (하지만 계속 이렇게 할 필요는 없습니다) 각 모듈 M을 다음과 같이 끝내는 것입니다:

if __name__ == "__main__":
    import doctest
    doctest.testmod()

그러면 doctest는 모듈 M의 독스트링을 검사합니다.

모듈을 스크립트로 실행하면 독스트링의 예제가 실행되고 검증됩니다:

python M.py

예제가 실패하지 않는 한 아무것도 표시되지 않습니다, 실패하면 실패한 예제와 실패 원인이 stdout으로 출력되고, 마지막 출력 줄은 ***Test Failed*** N failures.입니다. 여기서 N은 실패한 예제의 수입니다.

대신 -v 스위치로 실행해 보십시오:

python M.py -v

그러면 시도한 모든 예제에 대한 자세한 보고서가 표준 출력으로 출력되고, 끝에 정돈된 요약이 붙습니다.

verbose=Truetestmod()에 전달하여 상세 모드를 강제하거나, verbose=False를 전달하여 상세 모드를 금지할 수 있습니다. 두 경우 모두, sys.argvtestmod()에 의해 검사되지 않습니다 (따라서 -v를 전달하거나 그렇지 않아도 효과가 없습니다).

또한 testmod()를 실행하는 명령 줄 단축법이 있습니다. 파이썬 인터프리터에게 표준 라이브러리에서 직접 doctest 모듈을 실행하도록 지시하고 명령 줄에 모듈 이름(들)을 전달할 수 있습니다:

python -m doctest -v example.py

이렇게 하면 example.py를 독립 실행형 모듈로 임포트하고, testmod()를 실행합니다. 파일이 패키지 일부이고 그 패키지에서 다른 서브 모듈을 임포트하면, 올바르게 작동하지 않을 수 있음에 유의하십시오.

testmod()에 대한 자세한 내용은, 기본 API 절을 참조하십시오.

간단한 사용법: 텍스트 파일에 있는 예제 확인하기

doctest의 또 다른 간단한 활용은 텍스트 파일에 있는 대화형 예제를 테스트하는 것입니다. 이것은 testfile() 함수로 수행할 수 있습니다:

import doctest
doctest.testfile("example.txt")

이 짧은 스크립트는 example.txt 파일에 들어있는 대화형 파이썬 예제를 실행하고 검증합니다. 파일 내용은 하나의 거대한 독스트링인 것처럼 취급됩니다; 파일이 파이썬 프로그램일 필요가 없습니다! 예를 들어, example.txt에 다음과 같은 것이 들어있습니다:

The ``example`` module
======================

Using ``factorial``
-------------------

This is an example text file in reStructuredText format.  First import
``factorial`` from the ``example`` module:

    >>> from example import factorial

Now use it:

    >>> factorial(6)
    120

doctest.testfile("example.txt")를 실행하면 이 문서에 있는 에러를 찾습니다:

File "./example.txt", line 14, in example.txt
Failed example:
    factorial(6)
Expected:
    120
Got:
    720

testmod()와 마찬가지로, testfile()은 예제가 실패하지 않는 한 아무것도 표시하지 않습니다. 예제가 실패하면, 실패한 예제와 실패 원인이 testmod()와 같은 형식을 사용하여 stdout에 인쇄됩니다.

기본적으로, testfile()은 호출하는 모듈의 디렉터리에서 파일을 찾습니다. 다른 위치에서 파일을 찾도록 지시하는 데 사용할 수 있는 선택적 인자에 대한 설명은 기본 API 절을 참조하십시오.

testmod()와 마찬가지로, testfile()의 상세도는 -v 명령 줄 스위치나 선택적 키워드 인자 verbose를 사용하여 설정할 수 있습니다.

또한 testfile()를 실행하는 명령 줄 단축법이 있습니다. 파이썬 인터프리터에게 표준 라이브러리에서 직접 doctest 모듈을 실행하도록 지시하고 명령 줄에 파일 이름(들)을 전달할 수 있습니다:

python -m doctest -v example.txt

파일 이름은 .py로 끝나지 않으므로, doctesttestmod()가 아니라 testfile()로 실행되어야 한다고 추론합니다.

testfile()에 대한 자세한 내용은, 기본 API 절을 참조하십시오.

작동 방법

이 절에서는 doctest가 어떻게 작동하는지 자세히 설명합니다: 어떤 독스트링을 살피는지, 대화형 예제를 어떻게 찾는지, 사용하는 실행 컨텍스트는 무엇인지, 예외를 어떻게 처리하는지, 어떻게 옵션 플래그를 사용하여 동작을 제어하는지. 이것은 doctest 예제를 작성하기 위해 알아야 할 정보입니다; 이러한 예제에 대해 실제로 doctest를 실행하는 방법에 대한 자세한 내용은 다음 절을 참조하십시오.

어떤 독스트링을 검사합니까?

모듈 독스트링과 모든 함수, 클래스 및 메서드 독스트링이 검색됩니다. 모듈로 임포트 된 객체는 검색되지 않습니다.

또한, M.__test__가 존재하고 "참이면", 딕셔너리이어야 하고 각 항목은 (문자열) 이름을 함수 객체, 클래스 객체 또는 문자열에 매핑합니다. M.__test__에서 발견된 함수와 클래스 객체 독스트링이 검색되고, 문자열은 독스트링인 것처럼 처리됩니다. 출력에서, M.__test__의 키 K가 이름으로 나타납니다

<name of M>.__test__.K

발견된 모든 클래스는 포함된 메서드와 중첩된 클래스의 독스트링을 테스트하기 위해 유사하게 재귀적으로 검색됩니다.

CPython implementation detail: 버전 3.4 이전에는, C로 작성된 확장 모듈은 doctest가 완전히 검색하지 못했습니다.

독스트링 예제는 어떻게 인식됩니까?

대부분 대화형 콘솔 세션의 복사하여 붙여넣기가 잘 작동하지만, doctest는 특정 파이썬 셸의 정확한 에뮬레이션을 시도하지 않습니다.

>>> # comments are ignored
>>> x = 12
>>> x
12
>>> if x == 13:
...     print("yes")
... else:
...     print("no")
...     print("NO")
...     print("NO!!!")
...
no
NO
NO!!!
>>>

모든 예상 출력은 코드가 포함된 마지막 '>>> ' 또는 '... ' 줄 바로 다음에 나와야 하며, (있다면) 예상 출력은 다음 '>>> ' 나 전체 공백 줄까지 확장됩니다.

세부 사항:

  • 예상 출력은 전체 공백 줄을 포함할 수 없습니다. 그러한 줄은 예상 출력의 끝으로 인식되기 때문입니다. 예상 출력이 빈 줄을 포함하면, doctest 예제에서 빈 줄이 나타나는 곳에 <BLANKLINE>을 넣으십시오.

  • 모든 하드 탭 문자는 8열 탭 정지를 사용하여 스페이스로 확장됩니다. 테스트 된 코드에 의해 생성된 출력의 탭은 수정되지 않습니다. 샘플 출력의 모든 하드 탭이 확장되므로, 이것은 코드 출력에 하드 탭이 포함될 때 doctest가 통과할 수 있는 유일한 방법은, NORMALIZE_WHITESPACE 옵션이나 지시자가 유효한 경우뿐임을 의미합니다. 또는, 출력을 캡처하여 테스트 일부로 예상값과 비교하도록 테스트를 다시 작성할 수 있습니다. 이러한 소스의 탭 처리는 시행착오를 거쳐 얻어진 것이며, 가장 에러가 발생하지 않는 방법으로 입증되었습니다. 사용자 정의 DocTestParser 클래스를 작성하여 탭 처리에 다른 알고리즘을 사용하는 것도 가능합니다.

  • stdout으로의 출력은 캡처되지만, stderr로의 출력은 그렇지 않습니다 (예외 트레이스백은 다른 수단을 통해 캡처됩니다).

  • 대화식 세션에서 역 슬래시를 통해 줄을 계속하거나, 다른 이유로 백 슬래시를 사용하면, 날 독스트링(raw docstring)을 사용해서 역 슬래시를 입력한 그대로 유지해야 합니다:

    >>> def f(x):
    ...     r'''Backslashes in a raw docstring: m\n'''
    >>> print(f.__doc__)
    Backslashes in a raw docstring: m\n
    

    그렇지 않으면, 백 슬래시가 문자열 일부로 해석됩니다. 예를 들어, 위의 \n은 개행 문자로 해석됩니다. 또는, doctest 버전에서 각 백 슬래시를 중복시킬 수 있습니다 (그리고 날 문자열은 사용하지 않습니다):

    >>> def f(x):
    ...     '''Backslashes in a raw docstring: m\\n'''
    >>> print(f.__doc__)
    Backslashes in a raw docstring: m\n
    
  • 시작 열은 중요하지 않습니다:

    >>> assert "Easy!"
          >>> import math
              >>> math.floor(1.9)
              1
    

    그리고 예제를 시작한 초기 '>>> ' 줄에 나타나는 것만큼의 선행 공백을 예상 출력에서 제거합니다.

    flowdas

    여기서, 초기 '>>> ' 줄은 assert 문이 아니라 math.floor(1.9) 줄을 뜻합니다. 즉 예상 출력을 만드는 직전의 '>>> ' 줄을 뜻합니다. "초기"라는 단어는 '... ' 이 사용될 때를 고려한 것입니다.

실행 컨텍스트란 무엇입니까?

기본적으로, doctest가 테스트할 독스트링을 찾을 때마다, M의 전역 이름 공간(globals)의 앝은 복사를 사용하므로, 실행 중인 테스트는 모듈의 실제 전역을 변경하지 않고, M의 한 테스트가 실수로 다른 테스트가 작동하도록 만드는 부스러기를 남기지 않습니다. 이는 예제가 M에서 최상위 수준에 정의된 이름과 실행 중인 독스트링에서 앞서 정의한 이름을 자유롭게 사용할 수 있음을 의미합니다. 예제는 다른 독스트링에 정의된 이름을 볼 수 없습니다.

대신 globs=your_dicttestmod()testfile()로 전달하여 실행 컨텍스트로 여러분 자신의 딕셔너리를 사용하도록 할 수 있습니다.

예외는 어떻게 됩니까?

문제없습니다, 트레이스백이 예제에 의해 생성된 유일한 출력이기만 하면 됩니다: 그냥 트레이스백을 붙여넣으십시오. 1 트레이스백에는 빠르게 변할 가능성이 있는 세부 사항(예를 들어, 정확한 파일 경로와 줄 번호)이 포함되어 있으므로, 이것은 doctest가 수락할 내용에 유연하도록 신경 써야 하는 한 가지 사례입니다.

간단한 예:

>>> [1, 2, 3].remove(42)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list

이 doctest는 list.remove(x): x not in list 세부 정보를 포함하는 ValueError가 발생하면 성공합니다.

예외의 예상 출력은 다음 두 줄 중 한 가지가 예제의 첫 번째 줄과 같게 들여쓰기 된 트레이스백 헤더로 시작해야 합니다:

Traceback (most recent call last):
Traceback (innermost last):

트레이스백 헤더 다음에는 선택적인 트레이스백 스택이 오며, 그 내용은 doctest가 무시합니다. 보통 트레이스백 스택은 생략되거나, 대화형 세션에서 그대로 복사됩니다.

트레이스백 스택 다음에는 가장 흥미로운 부분이 옵니다: 예외 형과 세부 사항이 있는 줄. 대개 이것은 트레이스백의 마지막 줄이지만, 예외에 여러 줄로 구성된 세부 사항이 있으면 여러 줄로 확장될 수 있습니다:

>>> raise ValueError('multi\n    line\ndetail')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: multi
    line
detail

(ValueError로 시작하는) 마지막 세 줄이 예외의 형 및 세부 사항과 비교되고, 나머지는 무시됩니다.

모범 사례는 예제에 중요한 설명으로서의 가치를 추가하지 않는 한 트레이스백 스택을 생략하는 것입니다. 따라서 마지막 예제는 이렇게 하는 것이 더 좋습니다:

>>> raise ValueError('multi\n    line\ndetail')
Traceback (most recent call last):
    ...
ValueError: multi
    line
detail

트레이스백이 매우 특별하게 취급된다는 점에 유의하십시오. 특히, 다시 작성된 예제에서, ...의 사용은 doctest의 ELLIPSIS 옵션과 무관합니다. 이 예제의 줄임표는 생략하거나, 3개(혹은 300개)의 쉼표나 숫자 또는 몬티 파이썬 쇼의 들여쓰기 된 대본이어도 똑같이 잘 동작합니다.

한 번쯤 읽어야 할 세부 정보이지만, 기억할 필요는 없습니다:

  • Doctest는 예상 출력이 예외 트레이스백에서 온 것인지 일반 인쇄에서 온 것인지 추측할 수 없습니다. 그래서, 예를 들어, ValueError: 42 is prime을 예상하는 예제는 ValueError가 실제로 발생해도 통과하지만, 예제가 단지 그 트레이스백 텍스트를 출력해도 통과합니다. 실제로는, 일반 출력은 거의 트레이스백 헤더 줄로 시작하지 않으므로, 실제 문제가 되지는 않습니다.

  • (있다면) 트레이스백 스택의 각 줄은 예제의 첫 번째 줄보다 더 들여쓰기 되거나, 또는 영숫자(alphanumeric)가 아닌 문자로 시작해야 합니다. 트레이스백 헤더 뒤에 같은 정도로 들여쓰기 되고, 영숫자로 시작하는 첫 번째 줄은 예외 세부 사항의 시작으로 간주합니다. 물론 이것은 진짜 트레이스백에 잘 들어맞습니다.

  • IGNORE_EXCEPTION_DETAIL doctest 옵션을 지정하면, 가장 왼쪽 콜론 다음에 오는 모든 것과 예외 이름의 모듈 정보가 무시됩니다.

  • 대화형 셸은 일부 SyntaxError에서 트레이스백 헤더 줄을 생략합니다. 그러나 doctest는 트레이스백 헤더 줄을 사용하여 예외를 비 예외와 구별합니다. 따라서 트레이스백 헤더를 생략하는 SyntaxError를 테스트해야 하는 드문 경우에는, 트레이스백 헤더 줄을 수동으로 테스트 예제에 추가해야 합니다.

  • 일부 SyntaxError의 경우, 파이썬은 ^ 마커를 사용하여 구문 에러의 문자 위치를 표시합니다:

    >>> 1 1
      File "<stdin>", line 1
        1 1
          ^
    SyntaxError: invalid syntax
    

    에러의 위치를 나타내는 줄은 예외 형과 세부 사항 앞에 오므로, doctest가 점검하지 않습니다. 예를 들어, ^ 마커를 잘못된 위치에 넣어도, 다음 테스트가 통과합니다:

    >>> 1 1
      File "<stdin>", line 1
        1 1
        ^
    SyntaxError: invalid syntax
    

옵션 플래그

많은 옵션 플래그가 doctest의 다양한 동작을 제어합니다. 플래그의 기호 이름은 모듈 상수로 제공되며, 함께 비트별 OR되어 다양한 함수로 전달될 수 있습니다. 이 이름은 doctest 지시자에서도 사용될 수 있으며, -o 옵션을 통해 doctest 명령 줄 인터페이스로 전달될 수 있습니다.

버전 3.4에 추가: -o 명령 줄 옵션.

첫 번째 옵션 그룹은 테스트의 의미를 정의하는데, doctest가 실제 출력이 예제의 예상 출력과 일치하는지를 결정하는 측면을 제어합니다:

doctest.DONT_ACCEPT_TRUE_FOR_1

기본적으로, 예상 출력 블록에 1 만 있으면, 단지 1이나 True 만 포함된 실제 출력 블록을 일치하는 것으로 간주하며, 0False도 유사하게 다룹니다. DONT_ACCEPT_TRUE_FOR_1이 지정되면, 두 치환 모두 허용되지 않습니다. 기본 동작은 파이썬이 많은 함수의 반환형을 정수에서 논릿값으로 변경했다는 것을 반영합니다; "작은 정수" 출력을 예상하는 doctest가 이러한 경우에 여전히 작동합니다. 아마도 이 옵션은 사라지게 되겠지만, 몇 년 동안은 남아있을 겁니다.

doctest.DONT_ACCEPT_BLANKLINE

기본적으로, 예상 출력 블록에 <BLANKLINE> 문자열만 포함된 줄이 있으면, 해당하는 줄은 실제 출력의 빈 줄과 일치합니다. 진짜 빈 줄은 예상 출력을 끝내므로, 이것이 빈 줄을 예상하는 유일한 방법입니다. DONT_ACCEPT_BLANKLINE이 지정되면, 이 치환은 허용되지 않습니다.

doctest.NORMALIZE_WHITESPACE

지정되면, 모든 공백(빈칸과 개행) 시퀀스는 같게 취급됩니다. 예상 출력 내의 모든 공백 시퀀스는 실제 출력 내의 모든 공백 시퀀스와 일치합니다. 기본적으로, 공백은 정확히 일치해야 합니다. NORMALIZE_WHITESPACE는 예상 출력 줄이 매우 길고 소스의 여러 줄에 걸쳐 줄넘김하려는 경우에 특히 유용합니다.

doctest.ELLIPSIS

지정되면, 예상 출력의 줄임표(...)가 실제 출력의 모든 부분 문자열과 일치 할 수 있습니다. 여기에는 줄 경계를 넘는 부분 문자열과 빈 부분 문자열이 포함되므로, 사용을 간단하게 유지하는 것이 가장 좋습니다. 복잡한 사용은 정규식에서 .*를 쓸 때처럼 "이런, 너무 많이 일치하는군!" 과 같은 상황을 만들 수 있습니다.

doctest.IGNORE_EXCEPTION_DETAIL

지정하면, 예외를 예상하는 예제가, 예외 세부 사항이 일치하지 않아도 예상 형의 예외가 발생하면 통과합니다. 예를 들어, ValueError: 42를 예상하는 예제는 발생한 실제 예외가 ValueError: 3*14이면 통과하지만, 예를 들어 TypeError가 발생하면 실패합니다.

또한, 파이썬 3 doctest 보고서에 사용된 모듈 이름도 무시합니다. 따라서 이 두 변형은 이 플래그가 지정되면 테스트가 파이썬 2.7이나 파이썬 3.2(또는 이후 버전)에서 실행되는지와 관계없이 작동합니다:

>>> raise CustomError('message')
Traceback (most recent call last):
CustomError: message

>>> raise CustomError('message')
Traceback (most recent call last):
my_module.CustomError: message

ELLIPSIS를 사용하여 예외 메시지의 세부 사항을 무시할 수도 있지만, 그러한 테스트는 모듈 세부 사항이 예외 이름의 일부로 인쇄되는지에 따라 여전히 실패할 수 있음에 유의하십시오. IGNORE_EXCEPTION_DETAIL과 파이썬 2.3의 세부 사항을 사용하는 것은 또한 예외 세부 사항에 신경 쓰지 않고 여전히 파이썬 2.3이나 그 이전 버전(이 배포는 doctest 지시자를 지원하지 않고 무의미한 주석으로 무시합니다)에서 통과하는 doctest를 작성하는 유일하게 명확한 방법입니다. 예를 들면:

>>> (1, 2)[3] = 'moo'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object doesn't support item assignment

는 플래그가 지정될 때 파이썬 2.3 이후 버전에서 통과합니다. 파이썬 2.4에서 세부 사항이 "doesn't" 대신 "does not"으로 변경되었음에도 통과합니다.

버전 3.2에서 변경: IGNORE_EXCEPTION_DETAIL은 이제 테스트 중인 예외를 포함하는 모듈과 관련된 정보도 무시합니다.

doctest.SKIP

지정되면, 예제를 전혀 실행하지 않습니다. 이것은 doctest 예제가 설명서와 테스트 케이스의 두 가지 역할을 하는 문맥에서, 설명을 위해 예제를 포함해야 하지만 검사하지는 않아야 할 때 유용할 수 있습니다. 예를 들어, 예제의 출력이 임의적일 수 있습니다; 또는 예제가 테스트 구동기에서 사용할 수 없는 자원에 의존할 수 있습니다.

SKIP 플래그는 임시로 "주석 처리한" 예제를 위해 사용될 수도 있습니다.

doctest.COMPARISON_FLAGS

위의 모든 비교 플래그를 함께 OR 한 비트 마스크.

두 번째 옵션 그룹은 테스트 실패가 보고되는 방식을 제어합니다:

doctest.REPORT_UDIFF

지정되면, 여러 줄의 예상 및 실제 출력을 수반하는 실패가 통합(unified) diff를 사용하여 표시됩니다.

doctest.REPORT_CDIFF

지정되면, 여러 줄의 예상 및 실제 출력을 수반하는 실패가 문맥(context) diff를 사용하여 표시됩니다.

doctest.REPORT_NDIFF

지정되면, 차이점은 널리 사용되는 ndiff.py 유틸리티와 같은 알고리즘을 사용하여, difflib.Differ로 계산됩니다. 이 방법은 줄 간의 차이뿐만 아니라 줄 안에서의 차이점을 표시하는 유일한 방법입니다. 예를 들어, 예상 출력 줄에 숫자 1이 포함된 줄에 실제 출력이 문자 l을 포함하고 있으면, 일치하지 않는 열 위치를 나타내는 캐럿(caret)이 들어간 줄이 삽입됩니다.

doctest.REPORT_ONLY_FIRST_FAILURE

지정되면, 각 doctest에서 실패한 첫 번째 예제를 표시하지만, 나머지 모든 예제에 대해서는 출력을 억제합니다. 이렇게 하면 doctest가 이전의 실패로 인해 망가진 올바른 예제를 보고하지 않게 되지만, 첫 번째 실패와 무관하게 실패한 잘못된 예제를 숨길 수도 있습니다. REPORT_ONLY_FIRST_FAILURE가 지정될 때, 나머지 예제는 여전히 실행되며, 보고된 총실패 수에 포함됩니다; 출력만 억제됩니다.

doctest.FAIL_FAST

지정되면, 첫 번째 실패 예제 후에 종료하고, 나머지 예제를 실행하지 않습니다. 따라서, 보고되는 실패 횟수는 최대 1입니다. 이 플래그는 디버깅 중에 유용할 수 있습니다, 첫 번째 실패 이후의 예제는 디버깅 출력조차 생성하지 않기 때문입니다.

doctest 명령 줄은 옵션 -f-o FAIL_FAST의 축약으로 받아들입니다.

버전 3.4에 추가.

doctest.REPORTING_FLAGS

위의 모든 보고(reporting) 플래그를 함께 OR 한 비트 마스크.

새로운 옵션 플래그 이름을 등록하는 방법도 있습니다만, 서브 클래스를 통해 doctest 내부를 확장하려고 하지 않는 한 유용하지는 않습니다:

doctest.register_optionflag(name)

지정된 이름으로 새로운 옵션 플래그를 만들고, 새로운 플래그의 정숫값을 반환합니다. register_optionflag()OutputCheckerDocTestRunner를 서브 클래싱할 때 서브 클래스가 지원하는 새 옵션을 만들 때 사용할 수 있습니다. register_optionflag()는 항상 다음의 관용구를 사용하여 호출해야 합니다:

MY_FLAG = register_optionflag('MY_FLAG')

지시자

Doctest 지시자를 사용하면 개별 예제의 옵션 플래그를 수정할 수 있습니다. Doctest 지시자는 예제의 소스 코드 뒤에 오는 특수한 파이썬 주석입니다:

directive             ::=  "#" "doctest:" directive_options
directive_options     ::=  directive_option ("," directive_option)\*
directive_option      ::=  on_or_off directive_option_name
on_or_off             ::=  "+" \| "-"
directive_option_name ::=  "DONT_ACCEPT_BLANKLINE" \| "NORMALIZE_WHITESPACE" \| ...

+-와 지시자 옵션 이름 사이의 공백은 허용되지 않습니다. 지시자 옵션 이름은 위에 설명된 옵션 플래그 이름 중 하나일 수 있습니다.

예제의 doctest 지시자는 그 단일 예제에 대한 doctest의 동작을 수정합니다. 이름 붙인 동작을 활성화하려면 +를 사용하고, 비활성화하려면 -를 사용하십시오.

예를 들어, 이 테스트는 통과합니다:

>>> print(list(range(20))) 
[0,   1,  2,  3,  4,  5,  6,  7,  8,  9,
10,  11, 12, 13, 14, 15, 16, 17, 18, 19]

flowdas

doctest 지시자는 테스트를 위한 것이기 때문에 설명서로 렌더링할 때는 표시하지 않습니다. 바람직한 동작이기는 하지만 doctest 지시자 자체를 설명할 때는 문제가 됩니다. 실제로는 이렇게 지시자가 들어가 있습니다:

print(list(range(20))) # doctest: +NORMALIZE_WHITESPACE

지시자가 없으면 실패하는데, 실제 출력에는 한 자리 숫자 리스트 요소 앞에 두 개의 공백이 없기도 하고, 실제 출력은 한 줄이기 때문입니다. 이 테스트도 통과하는데, 그러기 위해서 역시 지시자가 필요합니다:

>>> print(list(range(20))) 
[0, 1, ..., 18, 19]

flowdas

실제로는 이렇게 지시자가 들어가 있습니다:

print(list(range(20))) # doctest: +ELLIPSIS

하나의 물리적 줄에 여러 개의 지시자를 쉼표로 구분하여 사용할 수 있습니다:

>>> print(list(range(20))) 
[0,    1, ...,   18,    19]

flowdas

실제로는 이렇게 지시자가 들어가 있습니다:

print(list(range(20))) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE

하나의 예제에 여러 개의 지시자 주석이 사용되면, 모두 결합합니다:

>>> print(list(range(20))) 
...                        
[0,    1, ...,   18,    19]

flowdas

실제로는 이렇게 지시자가 들어가 있습니다:

print(list(range(20))) # doctest: +ELLIPSIS
                       # doctest: +NORMALIZE_WHITESPACE

앞의 예가 보여주듯이, 여러분의 예제에 지시자만 포함된 ... 줄을 추가할 수 있습니다. 예가 너무 길어서 지시자가 같은 줄에 편안하게 들어갈 수 없을 때 유용할 수 있습니다:

>>> print(list(range(5)) + list(range(10, 20)) + list(range(30, 40)))
... 
[0, ..., 4, 10, ..., 19, 30, ..., 39]

flowdas

실제로는 이렇게 지시자가 들어가 있습니다:

print(list(range(5)) + list(range(10, 20)) + list(range(30, 40)))
# doctest: +ELLIPSIS

모든 옵션은 기본적으로 비활성화되고, 지시자가 표시된 예제에만 적용되므로, (지시자에 +를 통해) 옵션을 활성화하는 것이 일반적으로 유일한 의미 있는 선택입니다. 하지만, doctest를 실행하는 함수에 옵션 플래그를 전달하여 다른 기본값을 설정할 수도 있습니다. 이럴 때, 지시자에서 -를 통해 옵션을 비활성화하는 것이 유용할 수 있습니다.

경고

doctest는 예상 출력에서 정확한 일치를 요구하는 것에 심각합니다. 단일 문자가 일치하지 않아도 테스트가 실패합니다. 여러분이 출력에 있어서 파이썬이 정확히 무엇을 보장하고 무엇을 보장하지 않는지 배워감에 따라, 이것은 아마도 여러분을 몇 번 놀라게 할 것입니다. 예를 들어, 집합을 인쇄할 때, 파이썬은 원소가 특정 순서로 인쇄되는 것을 보장하지 않으므로, 다음과 같은 테스트는

>>> foo()
{"Hermione", "Harry"}

취약합니다! 한 가지 해결 방법은 다음과 같습니다

>>> foo() == {"Hermione", "Harry"}
True

대신에. 또 다른 방법은

>>> d = sorted(foo())
>>> d
['Harry', 'Hermione']

참고

파이썬 3.6 이전에는, 딕셔너리를 인쇄할 때, 파이썬은 키-값 쌍이 특정 순서로 인쇄되는 것을 보증하지 않았습니다.

다른 것들도 있지만, 아마 아이디어를 얻었을 겁니다.

또 다른 나쁜 생각은 객체 주소를 포함하는 것들을 출력하는 것입니다

>>> id(1.0) # 때로 실패할 것이 확실합니다
7948648
>>> class C: pass
>>> C()   # 인스턴스에 대한 기본 repr()은 주소를 포함합니다
<__main__.C instance at 0x00AC18F0>

ELLIPSIS 지시자는 마지막 예제를 다루는 좋은 접근법을 제공합니다

>>> C() 
<__main__.C instance at 0x...>

flowdas

실제로는 이렇게 지시자가 들어가 있습니다:

C() #doctest: +ELLIPSIS

부동 소수점 숫자도 플랫폼에 따라 약간의 출력 변동이 있습니다. 파이썬이 float 포매팅을 플랫폼 C 라이브러리에 위임하고 있고, 이때 C 라이브러리의 품질이 크게 다르기 때문입니다.

>>> 1./7  # 위험합니다
0.14285714285714285
>>> print(1./7) # 더 안전합니다
0.142857142857
>>> print(round(1./7, 6)) # 훨씬 더 안전합니다
0.142857

I/2.**J 형식의 숫자는 모든 플랫폼에서 안전하며, 저는 종종 이런 형식의 숫자를 만들도록 doctest 예제를 꾸밉니다:

>>> 3./4  # 완전히 안전합니다
0.75

flowdas

정수(또는 정숫값을 갖는 float)를 2의 거듭제곱으로 나눈 값은, 유효 숫자가 충분하다면 이진 부동 소수점으로 정확히 표현되고, 십진수로 변환할 때 자리 올림 오차가 발생하지 않습니다.

간단한 분수는 또한 사람들이 이해하기가 더 쉬우므로, 더 좋은 설명서가 되도록 합니다.

기본 API

testmod()testfile() 함수는 대부분 기본 사용에 충분한 doctest에 대한 간단한 인터페이스를 제공합니다. 이 두 함수에 대한 덜 형식적인 소개는 섹션 간단한 사용법: 독스트링에 있는 예제 확인하기간단한 사용법: 텍스트 파일에 있는 예제 확인하기를 참조하십시오.

doctest.testfile(filename, module_relative=True, name=None, package=None, globs=None, verbose=None, report=True, optionflags=0, extraglobs=None, raise_on_error=False, parser=DocTestParser(), encoding=None)

filename를 제외한 모든 인자는 선택적이며 키워드 형식으로 지정해야 합니다.

filename 파일에 있는 예제를 테스트합니다. (failure_count, test_count)를 반환합니다.

선택적 인자 module_relative는 filename을 해석하는 방법을 지정합니다:

  • module_relativeTrue(기본값)이면, filename는 OS 독립적 모듈 상대 경로를 지정합니다. 기본적으로, 이 경로는 호출하는 모듈의 디렉터리에 상대적입니다; 그러나 package 인자가 지정되면, 해당 패키지에 상대적입니다. OS 독립성을 보장하기 위해, filename/ 문자를 사용하여 경로 세그먼트를 분리해야 하며, 절대 경로일 수 없습니다 (즉, /로 시작할 수 없습니다).

  • module_relativeFalse이면, filename은 OS 특정 경로를 지정합니다. 경로는 절대나 상대일 수 있습니다; 상대 경로는 현재 작업 디렉터리를 기준으로 해석됩니다.

선택적 인자 name은 테스트의 이름을 제공합니다; 기본적으로, 또는 None이면, os.path.basename(filename)이 사용됩니다.

선택적 인자 package는 디렉터리가 모듈 상대 filename의 기본 디렉터리로 사용될 파이썬 패키지나 파이썬 패키지의 이름입니다. 패키지를 지정하지 않으면, 호출하는 모듈의 디렉터리가 모듈 상대 filename의 기본 디렉터리로 사용됩니다. module_relativeFalse일 때 package를 지정하는 것은 에러입니다.

선택적 인자 globs는 예제를 실행할 때 전역으로 사용될 딕셔너리를 제공합니다. doctest를 위해 이 딕셔너리의 새 얕은 사본이 만들어지므로, 예제는 깨끗한 서판으로 시작합니다. 기본적으로, 또는 None이면, 새 빈 딕셔너리가 사용됩니다.

선택적 인자 extraglobs는 예제를 실행하는 데 사용되는 전역에 병합될 딕셔너리를 제공합니다. 이것은 dict.update()처럼 작동합니다: globsextraglobs에 공통 키가 있으면, extraglobs의 연관된 값이 병합된 딕셔너리에 나타납니다. 기본적으로, 또는 None이면, 추가 전역은 사용되지 않습니다. doctest의 매개 변수화를 허용하는 고급 기능입니다. 예를 들어, doctest는 클래스의 일반 이름을 사용하여 베이스 클래스용으로 작성할 수 있습니다, 그런 다음 일반 이름을 테스트할 서브 클래스에 매핑하는 extraglobs 딕셔너리를 전달하여 임의의 수의 서브 클래스를 테스트하는데 재사용할 수 있습니다.

선택적 인자 verbose가 참이면 많은 것들을 인쇄하고, 거짓이면 실패만 인쇄합니다; 기본적으로, 또는 None이면, '-v'sys.argv에 있을 때만 참입니다.

선택적 인자 report가 참이면 끝에 요약을 인쇄하고, 그렇지 않으면 끝에 아무것도 인쇄하지 않습니다. verbose 모드에서는 요약 정보가 상세히 표시되며, 그렇지 않으면 요약 정보는 매우 간단합니다 (사실, 모든 테스트가 통과되면 비어 있습니다).

선택적 인자 optionflags(기본값은 0)는 옵션 플래그의 비트별 OR를 취합니다. 옵션 플래그 절을 참조하십시오.

선택적 인자 raise_on_error의 기본값은 거짓입니다. 참이면, 예제에서 첫 번째 실패나 예기치 않은 예외가 발생할 때 예외가 발생합니다. 이것은 실패를 사후(post-mortem) 디버깅할 수 있도록 합니다. 기본 동작은 예제를 계속 실행하는 것입니다.

선택적 인자 parser는 파일에서 테스트를 추출하는 데 사용할 DocTestParser(또는 서브 클래스)를 지정합니다. 기본값은 일반 파서(즉, DocTestParser())입니다.

선택적 인자 encoding은 파일을 유니코드로 변환하는 데 사용할 인코딩을 지정합니다.

doctest.testmod(m=None, name=None, globs=None, verbose=None, report=True, optionflags=0, extraglobs=None, raise_on_error=False, exclude_empty=False)

모든 인자는 선택적이며, m을 제외한 모든 인자는 키워드 형식으로 지정해야 합니다.

모듈 m(또는 m가 제공되지 않았거나 None이면 모듈 __main__)에서 도달할 수 있는 함수와 클래스의 독스트링에 있는 예제를 테스트합니다. m.__doc__으로 시작합니다.

딕셔너리 m.__test__이 존재하고 None이 아니면, 여기에서 도달할 수 있는 예제도 테스트합니다. m.__test__는 이름(문자열)을 함수, 클래스 및 문자열에 매핑합니다; 함수와 클래스 독스트링에서 예제를 검색합니다; 문자열은 그것이 독스트링인 것처럼 직접 검색합니다.

모듈 m에 속하는 객체에 연결된 독스트링 만 검색합니다.

(failure_count, test_count)를 반환합니다.

선택적 인자 name은 모듈의 이름을 제공합니다; 기본적으로, 또는 None이면, m.__name__이 사용됩니다.

선택적 인자 exclude_empty의 기본값은 거짓입니다. 참이면, doctest가 발견되지 않은 객체는 고려 대상에서 제외됩니다. 기본값은 이전 버전과의 호환성을 위한 해킹입니다, 여전히 testmod()와 함께 doctest.master.summarize()를 사용하는 코드는 테스트가 없는 객체에 대해 계속 출력합니다. 새로운 DocTestFinder 생성자에 대한 exclude_empty 인자의 기본값은 참입니다.

선택적 인자 extraglobs, verbose, report, optionflags, raise_on_errorglobs는 위의 함수 testfile()와 같습니다만, globs의 기본값이 m.__dict__인 점이 다릅니다.

doctest.run_docstring_examples(f, globs, verbose=False, name="NoName", compileflags=None, optionflags=0)

객체 f와 관련된 예제를 테스트합니다. 여기서, f는 문자열, 모듈, 함수 또는 클래스 객체일 수 있습니다.

딕셔너리 인자 globs의 얕은 사본이 실행 컨텍스트에 사용됩니다.

선택적 인자 name은 실패 메시지에서 사용되며, 기본값은 "NoName"입니다.

선택적 인자 verbose가 참이면, 실패가 없어도 출력이 생성됩니다. 기본적으로, 출력은 예제가 실패할 때만 생성됩니다.

선택적 인자 compileflags는 예제를 실행할 때 파이썬 컴파일러에서 사용해야 하는 플래그 집합을 제공합니다. 기본적으로, 또는 None이면, globs에서 발견되는 퓨처 기능 집합에 해당하는 플래그가 추론됩니다.

선택적 인자 optionflags는 위의 함수 testfile()에서 처럼 작동합니다.

Unittest API

doctest된 모듈 모음이 늘어남에 따라, 모든 doctest를 체계적으로 실행하는 방법이 필요합니다. doctest는 doctest가 포함된 모듈과 텍스트 파일로부터 unittest 테스트 스위트를 만드는 데 사용할 수 있는 두 가지 함수를 제공합니다. unittest 테스트 탐색과 통합하려면, 테스트 모듈에 load_tests() 함수를 포함하십시오:

import unittest
import doctest
import my_module_with_doctests

def load_tests(loader, tests, ignore):
    tests.addTests(doctest.DocTestSuite(my_module_with_doctests))
    return tests

Doctest가 있는 텍스트 파일과 모듈로부터 unittest.TestSuite 인스턴스를 만드는 두 가지 주요 함수가 있습니다:

doctest.DocFileSuite(*paths, module_relative=True, package=None, setUp=None, tearDown=None, globs=None, optionflags=0, parser=DocTestParser(), encoding=None)

하나 이상의 텍스트 파일로부터 doctest 테스트를 unittest.TestSuite로 변환합니다.

반환된 unittest.TestSuite는 unittest 프레임워크에 의해 실행되고, 각 파일에 있는 대화식 예제를 실행합니다. 어떤 파일의 예제가 실패하면, 합성된 단위 테스트가 실패하고, 테스트를 포함하는 파일의 이름과 (때로는 근사치인) 줄 번호를 보여주는 failureException 예외가 발생합니다.

검사할 텍스트 파일을 하나 이상의 paths(문자열)로 전달합니다.

옵션은 키워드 인자로 제공될 수 있습니다:

선택적 인자 module_relativepaths에 있는 파일명을 해석하는 방법을 지정합니다:

  • module_relativeTrue(기본값)이면, paths의 각 파일명은 OS 독립적 모듈 상대 경로를 지정합니다. 기본적으로, 이 경로는 호출하는 모듈의 디렉터리에 상대적입니다; 그러나 package 인자가 지정되면, 해당 패키지에 상대적입니다. OS 독립성을 보장하기 위해, 각 파일명은 / 문자를 사용하여 경로 세그먼트를 분리해야 하며, 절대 경로일 수 없습니다 (즉, /로 시작할 수 없습니다).

  • module_relativeFalse이면, paths의 각 파일명은 OS 특정 경로를 지정합니다. 경로는 절대나 상대일 수 있습니다; 상대 경로는 현재 작업 디렉터리를 기준으로 해석됩니다.

선택적 인자 package는 디렉터리가 paths의 모듈 상대 파일명의 기본 디렉터리로 사용될 파이썬 패키지나 파이썬 패키지의 이름입니다. 패키지를 지정하지 않으면, 호출하는 모듈의 디렉터리가 모듈 상대 파일명의 기본 디렉터리로 사용됩니다. module_relativeFalse일 때 package를 지정하는 것은 에러입니다.

선택적 인자 setUp은 테스트 스위트에 대한 사전 설정(set-up) 함수를 지정합니다. 이것은 각 파일에서 테스트를 실행하기 전에 호출됩니다. setUp 함수로 DocTest 객체가 전달됩니다. setUp 함수는 전달된 테스트의 globs 어트리뷰트를 통해 테스트 전역에 액세스할 수 있습니다.

선택적 인자 tearDown은 테스트 스위트에 사후 정리(tear-down) 함수를 지정합니다. 이것은 각 파일에서 테스트를 실행한 후에 호출됩니다. tearDown 함수로 DocTest 객체가 전달됩니다. tearDown 함수는 전달된 테스트의 globs 어트리뷰트를 통해 테스트 전역에 액세스할 수 있습니다.

선택적 인자 globs는 테스트의 초기 전역 변수를 포함하는 딕셔너리입니다. 이 딕셔너리의 새 사본이 테스트마다 만들어집니다. 기본적으로, globs는 새로운 빈 딕셔너리입니다.

선택적 인자 optionflags는 테스트에 대한 기본 doctest 옵션을 지정하는데, 개별 옵션 플래그를 함께 OR 해서 만들어집니다. 옵션 플래그 절을 참조하십시오. 보고(reporting) 옵션을 설정하는 더 좋은 방법은 아래 함수 set_unittest_reportflags()를 참조하십시오.

선택적 인자 parser는 파일에서 테스트를 추출하는 데 사용할 DocTestParser(또는 서브 클래스)를 지정합니다. 기본값은 일반 파서(즉, DocTestParser())입니다.

선택적 인자 encoding은 파일을 유니코드로 변환하는 데 사용할 인코딩을 지정합니다.

전역 __file__DocFileSuite()를 사용하여 텍스트 파일에서 로드된 doctest에 제공된 전역에 추가됩니다.

doctest.DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, setUp=None, tearDown=None, checker=None)

모듈에 대한 doctest 테스트를 unittest.TestSuite로 변환합니다.

반환된 unittest.TestSuite는 unittest 프레임워크에 의해 실행되고, 모듈에 있는 각 doctest를 실행합니다. 어떤 doctest가 실패하면, 합성된 단위 테스트가 실패하고, 테스트를 포함하는 파일의 이름과 (때로는 근사치인) 줄 번호를 보여주는 failureException 예외가 발생합니다.

선택적 인자 module은 테스트할 모듈을 제공합니다. 모듈 객체나 (점으로 구분될 수 있는) 모듈 이름일 수 있습니다. 지정하지 않으면, 이 함수를 호출하는 모듈이 사용됩니다.

선택적 인자 globs는 테스트의 초기 전역 변수를 포함하는 딕셔너리입니다. 이 딕셔너리의 새 사본이 테스트마다 만들어집니다. 기본적으로, globs는 새로운 빈 딕셔너리입니다.

선택적 인자 extraglobsglobs에 병합되는 전역 변수의 추가 집합을 지정합니다. 기본적으로, 추가 전역 변수는 사용되지 않습니다.

선택적 인자 test_finder는 모듈에서 doctest를 추출하는 데 사용되는 DocTestFinder 객체(또는 드롭 인 대체)입니다.

선택적 인자 setUp, tearDownoptionflags는 위의 함수 DocFileSuite()와 같습니다.

이 함수는 testmod()와 같은 검색 기법을 사용합니다.

버전 3.5에서 변경: module에 독스트링이 없으면 DocTestSuite()ValueError를 발생시키는 대신 빈 unittest.TestSuite를 반환합니다.

수면 아래에서, DocTestSuite()doctest.DocTestCase 인스턴스에서 unittest.TestSuite를 만들고, DocTestCaseunittest.TestCase의 서브 클래스입니다. DocTestCase는 여기에서 설명되지는 않지만 (내부 세부 사항입니다), 그것의 코드를 살펴보면 unittest 통합의 정확한 세부 사항에 대한 질문에 대한 답을 얻을 수 있습니다.

마찬가지로, DocFileSuite()doctest.DocFileCase 인스턴스에서 unittest.TestSuite를 만들고, DocFileCaseDocTestCase의 서브 클래스입니다.

따라서 unittest.TestSuite를 만드는 두 가지 방법 모두 DocTestCase의 인스턴스를 실행합니다. 이것은 미묘한 이유로 중요합니다: 여러분이 doctest 함수를 직접 실행할 때, 옵션 플래그를 doctest 함수에 전달하여 사용 중인 doctest 옵션을 직접 제어할 수 있습니다. 그러나, unittest 프레임워크를 작성한다면, unittest가 테스트가 언제 어떻게 실행되는지 궁극적으로 제어합니다. 프레임워크 저자는 일반적으로 doctest (아마도, 예를 들어, 명령 줄 옵션으로 지정하는) 보고(reporting) 옵션을 제어하려고 하지만, unittest를 통해 doctest 테스트 실행기로 옵션을 전달할 방법이 없습니다.

이러한 이유로, doctestunittest 지원에 특화된 doctest 보고(reporting) 플래그 개념을 다음 함수를 통해 지원합니다:

doctest.set_unittest_reportflags(flags)

사용할 doctest 보고 플래그를 설정합니다.

인자 flags는 옵션 플래그의 비트별 OR를 취합니다. 옵션 플래그 절을 참조하십시오. "보고 플래그"만 사용할 수 있습니다.

이것은 모듈 전역 설정이며, 모듈 unittest에 의해 실행되는 모든 미래의 doctest에 영향을 줍니다. DocTestCaserunTest() 메서드는 DocTestCase 인스턴스가 생성될 때 테스트 케이스에 대해 지정된 옵션 플래그를 봅니다. 보고 플래그가 지정되지 않았으면 (이것이 일반적이고 예상되는 경우입니다), doctestunittest보고 플래그는 옵션 플래그에 비트별 OR되고, 이렇게 손질된 옵션 플래그가 doctest를 실행하기 위해 만들어진 DocTestRunner 인스턴스로 전달됩니다. DocTestCase 인스턴스가 생성될 때 보고 플래그가 지정되었으면, doctestunittest 보고 플래그는 무시됩니다.

함수가 호출되기 전에 유효했던 unittest 보고 플래그의 값이 함수에 의해 반환됩니다.

고급 API

기본 API는 doctest를 사용하기 쉽게 하기 위한 간단한 래퍼입니다. 그것은 매우 유연하며, 대부분 사용자의 요구를 충족시켜야 합니다; 그러나, 테스팅에 대한 세밀한 제어가 필요하거나, doctest의 기능을 확장하려면, 고급 API를 사용해야 합니다.

고급 API는 doctest 케이스에서 추출한 대화식 예제를 저장하는 데 사용되는 두 개의 컨테이너 클래스를 중심으로 돌아갑니다:

  • Example: 예상 출력과 쌍을 이루는 단일 파이썬 문장.

  • DocTest: 일반적으로 단일 독스트링이나 텍스트 파일에서 추출된 Example의 모음.

doctest 예제를 찾고, 구문 분석하고, 실행하고, 검사하기 위해 추가 처리 클래스가 정의됩니다:

  • DocTestFinder: 주어진 모듈에서 모든 독스트링을 찾고, DocTestParser를 사용하여 대화식 예제가 들어있는 모든 독스트링에서 DocTest를 만듭니다.

  • DocTestParser: 문자열(가령 객체의 독스트링)에서 DocTest 객체를 만듭니다.

  • DocTestRunner: DocTest에 있는 예제를 실행하고, OutputChecker를 사용하여 출력을 확인합니다.

  • OutputChecker: doctest 예제의 실제 출력을 예상 출력과 비교하고, 그들이 일치하는지 결정합니다.

이러한 처리 클래스 간의 관계는 다음 도표에 요약되어 있습니다:

                            list of:
+------+                   +---------+
|module| --DocTestFinder-> | DocTest | --DocTestRunner-> results
+------+    |        ^     +---------+     |       ^    (printed)
            |        |     | Example |     |       |
            v        |     |   ...   |     v       |
           DocTestParser   | Example |   OutputChecker
                           +---------+

DocTest 객체

class doctest.DocTest(examples, globs, name, filename, lineno, docstring)

단일 이름 공간에서 실행되어야 하는 doctest 예제의 모음. 생성자 인자는 같은 이름의 어트리뷰트를 초기화하는 데 사용됩니다.

DocTest는 다음 어트리뷰트를 정의합니다. 이들은 생성자에 의해 초기화되며, 직접 수정하면 안 됩니다.

examples

이 테스트가 실행해야 하는 개별 대화형 파이썬 예제를 인코딩하는 Example 객체의 리스트.

globs

예제가 실행되어야 하는 이름 공간 (일명 전역). 이름을 값에 매핑하는 딕셔너리입니다. 예제가 만든 이름 공간의 모든 변경 사항(가령 새 변수 바인딩)은 테스트가 실행된 후 globs에 반영됩니다.

name

DocTest를 식별하는 문자열 이름. 일반적으로, 테스트가 추출된 객체나 파일의 이름입니다.

filename

DocTest가 추출된 파일의 이름; 또는 파일 이름을 알 수 없거나 파일에서 DocTest가 추출되지 않았으면 None.

lineno

DocTest가 시작되는 filename 내의 줄 번호, 또는 줄 번호가 없으면 None. 이 줄 번호는 파일의 시작 부분을 기준으로 0에서 시작합니다.

docstring

테스트가 추출된 문자열, 또는 문자열이 없거나 테스트가 문자열에서 추출되지 않았으면 None.

Example 객체

class doctest.Example(source, want, exc_msg=None, lineno=0, indent=0, options=None)

파이썬 문장과 예상 출력으로 구성된 단일 대화형 예제. 생성자 인자는 같은 이름의 어트리뷰트를 초기화하는 데 사용됩니다.

Example는 다음 어트리뷰트를 정의합니다. 이들은 생성자에 의해 초기화되며, 직접 수정하면 안 됩니다.

source

예제의 소스 코드가 포함된 문자열. 이 소스 코드는 단일 파이썬 문으로 구성되며 항상 개행으로 끝납니다; 생성자는 필요하면 개행 문자를 추가합니다.

want

예제의 소스 코드를 실행할 때 (stdout이나 예외 발생 시 트레이스백으로부터) 예상되는 출력. want는 출력이 예상되지 않으면 빈 문자열이고, 그렇지 않으면 개행으로 끝납니다. 생성자는 필요하면 개행을 추가합니다.

exc_msg

예제가 예외를 생성할 것으로 예상되면, 예제에서 생성된 예외 메시지; 또는 예외를 생성할 것으로 예상되지 않으면 None. 이 예외 메시지는 traceback.format_exception_only()의 반환 값과 비교됩니다. exc_msgNone이 아니면 개행으로 끝납니다. 생성자는 필요하면 개행을 추가합니다.

lineno

이 예제가 시작하는 이 예제를 포함하는 문자열 내의 줄 번호. 이 줄 번호는 포함하는 문자열의 시작 부분을 기준으로 0에서 시작합니다.

indent

포함하는 문자열 내에서의 이 예제의 들여쓰기, 즉 예제의 첫 번째 프롬프트 앞에 오는 스페이스 문자의 수.

options

옵션 플래그에서 TrueFalse 로 매핑하는 딕셔너리, 이 예제의 기본 옵션을 재정의하는 데 사용됩니다. 이 딕셔너리에 포함되지 않은 옵션 플래그는 (DocTestRunneroptionflags에 지정된 대로) 기본값으로 남습니다. 기본적으로, 아무런 옵션도 설정되지 않습니다.

DocTestFinder 객체

class doctest.DocTestFinder(verbose=False, parser=DocTestParser(), recurse=True, exclude_empty=True)

주어진 객체에 관련된 DocTest를 그것의 독스트링과 그것이 포함하는 객체의 독스트링으로부터 추출하기 위해서 사용되는 처리 클래스. DocTest는 모듈, 클래스, 함수, 메서드, 정적 메서드, 클래스 메서드 및 프로퍼티에서 추출할 수 있습니다.

선택적 인자 verbose는 파인더가 검색한 객체를 표시하는 데 사용될 수 있습니다. 기본값은 False (출력 없음)입니다.

선택적 인자 parser는 독스트링에서 doctest를 추출하는 데 사용되는 DocTestParser 객체 (또는 드롭 인 대체)를 지정합니다.

선택적 인자 recurse가 거짓이면, DocTestFinder.find()는 오직 주어진 객체만을 검사 할 뿐, 포함된 객체는 검사하지 않습니다.

선택적 인자 exclude_empty가 거짓이면, DocTestFinder.find()는 빈 독스트링을 가진 객체에 대한 테스트를 포함합니다.

DocTestFinder는 다음 메서드를 정의합니다:

find(obj[, name][, module][, globs][, extraglobs])

obj의 독스트링이나 포함된 객체의 독스트링으로 정의된 DocTest의 리스트를 반환합니다.

선택적 인자 name은 객체의 이름을 지정합니다. 이 이름은 반환된 DocTest의 이름을 구성하는 데 사용됩니다. name이 지정되지 않으면, obj.__name__이 사용됩니다.

선택적 매개 변수 module은 주어진 객체를 포함하는 모듈입니다. 모듈이 지정되지 않거나 None이면, 테스트 파인더는 자동으로 올바른 모듈을 판별하려고 시도합니다. 객체의 모듈은 다음과 같이 사용됩니다:

  • globs가 지정되지 않으면, 기본 이름 공간으로.

  • DocTestFinder가 다른 모듈에서 임포트 된 객체에서 DocTest를 추출하지 못하도록 하려고. (module이 아닌 다른 모듈을 가진 포함 된 객체는 무시됩니다.)

  • 객체를 포함하는 파일의 이름을 찾으려고.

  • 해당 파일 내에서 객체의 줄 번호를 찾는 데 도움이 됩니다.

moduleFalse면, 모듈을 찾으려고 시도하지 않습니다. 이것은 눈에 띄지 않는데, 대부분 doctest 자체를 테스트할 때 사용합니다: moduleFalse이거나, None이지만 자동으로 찾을 수 없으면, 모든 객체는 (존재하지 않는) 모듈에 속한 것으로 간주하므로, 포함된 모든 객체에서 (재귀적으로) doctest를 검색합니다.

DocTest에 대한 전역은 globsextraglobs(extraglobs의 바인딩이 globs의 바인딩에 우선합니다)를 결합하여 구성됩니다. 각 DocTest마다 전역 딕셔너리의 새 얕은 복사본이 만들어집니다. globs를 지정하지 않으면, 기본값은 모듈이 지정되었다면 모듈의 __dict__, 또는 그렇지 않으면 {}입니다. extraglobs가 지정되지 않으면, 기본값은 {}입니다.

DocTestParser 객체

class doctest.DocTestParser

문자열에서 대화형 예제를 추출하고, 이를 사용하여 DocTest 객체를 만드는 데 사용되는 처리 클래스.

DocTestParser는 다음 메서드를 정의합니다:

get_doctest(string, globs, name, filename, lineno)

주어진 문자열에서 모든 doctest 예제를 추출하고, 이를 DocTest 객체로 모읍니다.

globs, name, filenamelineno는 새 DocTest 객체의 어트리뷰트입니다. 자세한 내용은 DocTest 설명서를 참조하십시오.

get_examples(string, name='<string>')

주어진 문자열에서 모든 doctest 예제를 추출하고, 이를 Example 객체의 리스트로 반환합니다. 줄 번호는 0부터 시작합니다. 선택적 인자 name은, 이 문자열을 식별하는 이름이며, 에러 메시지에만 사용됩니다.

parse(string, name='<string>')

주어진 문자열을 예제와 중간에 있는 텍스트로 나누고, 이를 Example와 문자열이 번갈아 나오는 리스트로 반환합니다. Example의 줄 번호는 0부터 시작합니다. 선택적 인자 name은, 이 문자열을 식별하는 이름이며, 에러 메시지에만 사용됩니다.

DocTestRunner 객체

class doctest.DocTestRunner(checker=None, verbose=None, optionflags=0)

DocTest에 있는 대화형 예제를 실행하고 검증하는 데 사용되는 처리 클래스.

예상 출력과 실제 출력 간의 비교는 OutputChecker에 의해 수행됩니다. 이 비교는 여러 옵션 플래그로 사용자 정의할 수 있습니다; 자세한 내용은 옵션 플래그 절을 참조하십시오. 옵션 플래그로 충분하지 않으면, OutputChecker의 서브 클래스를 생성자에 전달하여 비교를 사용자 정의할 수도 있습니다.

테스트 실행기의 디스플레이 출력은 두 가지 방법으로 제어할 수 있습니다. 첫째, 출력 함수를 TestRunner.run()로 전달할 수 있습니다; 이 함수는 표시되어야 하는 문자열로 호출됩니다. 기본값은 sys.stdout.write입니다. 출력을 캡처하는 것으로 충분하지 않으면, DocTestRunner를 서브 클래싱하고 report_start(), report_success(), report_unexpected_exception()report_failure() 메서드를 재정의하여 디스플레이 출력을 사용자 정의할 수 있습니다.

선택적 키워드 인자 checker는 예상 출력을 doctest 예제의 실제 출력과 비교하는 데 사용되는 OutputChecker 객체(또는 드롭 인 대체)를 지정합니다.

선택적 키워드 인자 verboseDocTestRunner의 상세도를 제어합니다. verboseTrue이면, 실행될 때 각 예제에 대한 정보가 인쇄됩니다. verboseFalse이면, 실패만 인쇄됩니다. verbose가 지정되지 않거나 None이면, 명령 줄 스위치 -v가 사용될 때만 상세 출력이 사용됩니다.

선택적 키워드 인자 optionflags는 테스트 실행기가 예상 출력을 실제 출력과 비교하는 방법과 실패를 표시하는 방법을 제어하는 데 사용할 수 있습니다. 자세한 내용은 옵션 플래그 절을 참조하십시오.

DocTestRunner는 다음 메서드를 정의합니다:

report_start(out, test, example)

테스트 러너가 주어진 예제를 처리하려고 한다고 보고합니다. 이 메서드는 DocTestRunner의 서브 클래스가 출력을 사용자 정의할 수 있도록 제공됩니다; 직접 호출해서는 안 됩니다.

example은 처리될 예제입니다. test예제를 포함하는 테스트입니다. outDocTestRunner.run()에 전달된 출력 함수입니다.

report_success(out, test, example, got)

주어진 예제가 성공적으로 실행되었음을 보고합니다. 이 메서드는 DocTestRunner의 서브 클래스가 출력을 사용자 정의할 수 있도록 제공됩니다; 직접 호출해서는 안 됩니다.

example은 처리될 예제입니다. got은 예제의 실제 출력입니다. testexample을 포함하는 테스트입니다. outDocTestRunner.run()에 전달된 출력 함수입니다.

report_failure(out, test, example, got)

주어진 예제가 실패했음을 보고합니다. 이 메서드는 DocTestRunner의 서브 클래스가 출력을 사용자 정의할 수 있도록 제공됩니다; 직접 호출해서는 안 됩니다.

example은 처리될 예제입니다. got은 예제의 실제 출력입니다. testexample을 포함하는 테스트입니다. outDocTestRunner.run()에 전달된 출력 함수입니다.

report_unexpected_exception(out, test, example, exc_info)

주어진 예제가 예기치 않은 예외를 발생시켰다고 보고합니다. 이 메서드는 DocTestRunner의 서브 클래스가 출력을 사용자 정의할 수 있도록 제공됩니다; 직접 호출해서는 안 됩니다.

example은 처리될 예제입니다. exc_info는 예기치 않은 예외에 대한 정보를 포함하는 튜플입니다 (sys.exc_info()에 의해 반환되는 것). testexample을 포함하는 테스트입니다. outDocTestRunner.run()에 전달된 출력 함수입니다.

run(test, compileflags=None, out=None, clear_globs=True)

test(DocTest 객체)에 있는 예제를 실행하고, 출력 함수 out을 사용하여 결과를 표시합니다.

예제는 이름 공간 test.globs에서 실행됩니다. clear_globs가 참(기본값)이면, 가비지 수집을 돕기 위해 테스트가 실행된 후 이 이름 공간이 지워집니다. 테스트가 완료된 후에 이름 공간을 검사하려면 clear_globs=False를 사용하십시오.

compileflags는 예제를 실행할 때 파이썬 컴파일러에서 사용해야 하는 플래그 집합을 제공합니다. 지정되지 않으면, globs에 적용되는 퓨처-임포트 플래그 집합이 기본값이 됩니다.

각 예제의 출력은 DocTestRunner의 출력 검사기를 사용하여 검사되며, 결과는 DocTestRunner.report_*() 메서드로 포맷됩니다.

summarize(verbose=None)

이 DocTestRunner가 실행 한 모든 테스트 케이스의 요약을 인쇄하고, 네임드 튜플 TestResults(failed, attempted)를 반환합니다.

선택적 verbose 인자는 요약이 얼마나 상세할지를 제어합니다. 상세도가 지정되지 않으면, DocTestRunner의 상세도가 사용됩니다.

OutputChecker 객체

class doctest.OutputChecker

doctest 예제의 실제 출력이 예상 출력과 일치하는지를 확인하는 데 사용되는 클래스. OutputChecker는 두 가지 메서드를 정의합니다: check_output()은 주어진 출력 쌍을 비교하고 일치하면 참을 반환합니다; output_difference()는 두 출력 간의 차이를 설명하는 문자열을 반환합니다.

OutputChecker는 다음 메서드를 정의합니다:

check_output(want, got, optionflags)

예제의 실제 출력(got)이 예상 출력(want)과 일치할 때만 True를 반환합니다. 이 문자열은 같으면 항상 일치하는 것으로 간주합니다; 그러나 테스트 실행기가 사용하는 옵션 플래그에 따라 몇 가지 정확하지 않은 일치 유형도 가능합니다. 옵션 플래그에 대한 자세한 정보는 옵션 플래그 절을 참조하십시오.

output_difference(example, got, optionflags)

주어진 예제(example)에 대한 예상 출력과 실제 출력(got)의 차이를 설명하는 문자열을 반환합니다. optionflagswantgot을 비교하는 데 사용되는 옵션 플래그 집합입니다.

디버깅

Doctest는 doctest 예제를 디버깅하기 위한 몇 가지 메커니즘을 제공합니다:

  • 몇몇 함수는 doctest를 파이썬 디버거 pdb에서 실행할 수 있는 실행 가능한 파이썬 프로그램으로 변환합니다.

  • DebugRunner 클래스는 첫 번째 실패한 예제에 대한 예외를 발생시키는 DocTestRunner의 서브 클래스이며 해당 예제에 대한 정보가 들어 있습니다. 이 정보는 예제에서 사후 디버깅을 수행하는 데 사용될 수 있습니다.

  • DocTestSuite()에 의해 생성된 unittest 케이스는 unittest.TestCase에 의해 정의된 debug() 메서드를 지원합니다.

  • doctest 예제에 pdb.set_trace()에 대한 호출을 추가 할 수 있습니다. 그러면 해당하는 줄이 실행될 때 파이썬 디버거로 들어갑니다. 그런 다음 변수의 현재 값을 검사하는 등의 일을 할 수 있습니다. 예를 들어, a.py가 다음과 같은 모듈 독스트링을 포함한다고 가정합시다:

    """
    >>> def f(x):
    ...     g(x*2)
    >>> def g(x):
    ...     print(x+3)
    ...     import pdb; pdb.set_trace()
    >>> f(3)
    9
    """
    

    그러면 대화형 파이썬 세션은 이런 식이 됩니다:

    >>> import a, doctest
    >>> doctest.testmod(a)
    --Return--
    > <doctest a[1]>(3)g()->None
    -> import pdb; pdb.set_trace()
    (Pdb) list
      1     def g(x):
      2         print(x+3)
      3  ->     import pdb; pdb.set_trace()
    [EOF]
    (Pdb) p x
    6
    (Pdb) step
    --Return--
    > <doctest a[0]>(2)f()->None
    -> g(x*2)
    (Pdb) list
      1     def f(x):
      2  ->     g(x*2)
    [EOF]
    (Pdb) p x
    3
    (Pdb) step
    --Return--
    > <doctest a[2]>(1)?()->None
    -> f(3)
    (Pdb) cont
    (0, 3)
    >>>
    

Doctest를 파이썬 코드로 변환하고, 디버거에서 합성 코드를 실행할 수 있는 함수들:

doctest.script_from_examples(s)

예제가 있는 텍스트를 스크립트로 변환합니다.

인자 s는 doctest 예제를 포함하는 문자열입니다. 문자열은 파이썬 스크립트로 변환됩니다. 여기서 s의 doctest 예제는 일반 코드로 변환되고, 나머지는 파이썬 주석으로 변환됩니다. 생성된 스크립트는 문자열로 반환됩니다. 예를 들어,

import doctest
print(doctest.script_from_examples(r"""
    Set x and y to 1 and 2.
    >>> x, y = 1, 2

    Print their sum:
    >>> print(x+y)
    3
"""))

는 다음과 같이 출력합니다:

# Set x and y to 1 and 2.
x, y = 1, 2
#
# Print their sum:
print(x+y)
# Expected:
## 3

이 함수는 다른 함수(아래 참조)에서 내부적으로 사용되지만, 대화형 파이썬 세션을 파이썬 스크립트로 변환하려고 할 때도 유용합니다.

doctest.testsource(module, name)

객체에 대한 doctest를 스크립트로 변환합니다.

인자 module은 doctest가 관심 대상인 객체를 포함하는 모듈 객체나 모듈의 점으로 구분된 이름입니다. 인자 name은 doctest가 관심 대상인 객체의 (모듈 내에서의) 이름입니다. 결과는 위의 script_from_examples()에서 설명한 대로 파이썬 스크립트로 변환된 객체의 독스트링을 포함하는 문자열입니다. 예를 들어, 모듈 a.py에 최상위 함수 f()가 포함되었다면,

import a, doctest
print(doctest.testsource(a, "a.f"))

는 doctest가 코드로 변환되고 나머지는 주석으로 배치된, 함수 f()의 독스트링의 스크립트 버전을 인쇄합니다.

doctest.debug(module, name, pm=False)

객체의 doctest를 디버그합니다.

modulename 인자는 위의 함수 testsource()와 같습니다. 명명된 객체의 독스트링에 대한 합성된 파이썬 스크립트가 임시 파일에 기록되고, 그 파일을 파이썬 디버거 pdb의 제어하에 실행합니다.

module.__dict__의 얕은 사본이 지역과 전역 실행 컨텍스트 모두에 사용됩니다.

선택적 인자 pm은 사후 디버깅이 사용되는지를 제어합니다. pm이 참값이면, 스크립트 파일은 직접 실행되고, 처리되지 않은 예외를 발생시켜 스크립트가 종료될 때만 디버거가 개입합니다. 그럴 때, 사후 디버깅이 pdb.post_mortem()를 통해 호출되어, 처리되지 않은 예외로부터 온 트레이스백 객체를 전달합니다. pm이 지정되지 않았거나 거짓이면, 스크립트는 적절한 exec() 호출을 pdb.run()에 전달하여 시작부터 디버거에서 실행됩니다.

doctest.debug_src(src, pm=False, globs=None)

문자열에 있는 doctest를 디버그합니다.

doctest 예제를 포함하는 문자열이 src 인자를 통해 직접 지정된다는 점을 제외하면, 위의 함수 debug()과 같습니다.

선택적 인자 pm은 위의 함수 debug()에서와 같은 의미를 가집니다.

선택적 인자 globs는 지역과 전역 실행 컨텍스트 모두에 사용할 딕셔너리를 제공합니다. 지정되지 않거나 None이면, 빈 딕셔너리가 사용됩니다. 지정되면, 딕셔너리의 얕은 사본이 사용됩니다.

DebugRunner 클래스와 이 클래스가 발생시킬 수 있는 특별한 예외는 주로 테스트 프레임워크 작성자가 관심을 가지며, 여기에서는 대략적으로만 다룰 예정입니다. 자세한 내용은 소스 코드, 특히 DebugRunner의 독스트링(doctest입니다!)을 참조하십시오:

class doctest.DebugRunner(checker=None, verbose=None, optionflags=0)

실패를 만나자마자 예외를 발생시키는 DocTestRunner의 서브 클래스. 예기치 않은 예외가 발생하면, 테스트, 예제 및 원래 예외가 포함된 UnexpectedException 예외가 발생합니다. 출력이 일치하지 않으면, 테스트, 예제 및 실제 출력을 포함하는 DocTestFailure 예외가 발생합니다.

생성자 매개 변수와 메서드에 대한 자세한 내용은 고급 API 절의 DocTestRunner 설명서를 참조하십시오.

DebugRunner 인스턴스가 발생시킬 수 있는 두 가지 예외가 있습니다:

exception doctest.DocTestFailure(test, example, got)

doctest 예제의 실제 출력이 예상 출력과 일치하지 않는다는 것을 알리기 위해 DocTestRunner가 발생시키는 예외. 생성자 인자는 같은 이름의 어트리뷰트를 초기화하는 데 사용됩니다.

DocTestFailure는 다음 어트리뷰트를 정의합니다:

DocTestFailure.test

예제가 실패했을 때 실행 중이던 DocTest 객체.

DocTestFailure.example

실패한 Example.

DocTestFailure.got

예제의 실제 출력.

exception doctest.UnexpectedException(test, example, exc_info)

doctest 예제가 예기치 않은 예외를 발생시켰음을 알리기 위해 DocTestRunner가 발생시키는 예외. 생성자 인자는 같은 이름의 어트리뷰트를 초기화하는 데 사용됩니다.

UnexpectedException는 다음 어트리뷰트를 정의합니다:

UnexpectedException.test

예제가 실패했을 때 실행 중이던 DocTest 객체.

UnexpectedException.example

실패한 Example.

UnexpectedException.exc_info

sys.exc_info()에 의해 반환되는 것과 같은, 예기치 않은 예외에 대한 정보가 포함된 튜플.

맺음말

소개에서 언급했듯이, doctest는 다음 세 가지 주요 용도로 성장했습니다:

  1. 독스트링에 있는 예제 검사.

  2. 회귀 테스트.

  3. 실행 가능한 문서/문학적(literate) 테스트.

이러한 용도들은 다른 요구 사항을 가지며, 이를 구별하는 것이 중요합니다. 특히, 모호한 테스트 케이스로 독스트링을 채우는 것은 나쁜 설명서를 만듭니다.

독스트링을 작성할 때, 독스트링 예제를 주의해서 선택하십시오. 여기에는 배울 필요가 있는 기술이 있습니다---처음에는 자연스럽지 않을 수도 있습니다. 예제는 설명서에 진짜 가치를 부여해야 합니다. 좋은 예제는 종종 많은 단어의 가치가 있습니다. 주의 깊게 작업 된다면, 예제는 사용자에게 매우 가치 있을 것이며, 몇 년이 지나고 변함에 따라 여러 번 수집하는 데 드는 시간을 갚을 것입니다. 제 doctest 예제 중 하나가 "해가 없는" 변경 후에 얼마나 자주 작동을 멈추는지 지금도 놀라울 뿐입니다.

Doctest는 회귀 테스트를 위한 훌륭한 도구도 제공합니다. 특히 설명 텍스트를 생략하지 않는다면 더욱더 그렇습니다. 설명과 예제를 번갈아 보여줌으로써, 실제로 무엇이 왜 테스트 되는지를 추적하기가 훨씬 쉬워집니다. 테스트가 실패할 때, 좋은 설명은 문제가 무엇인지, 어떻게 고쳐야 하는지를 쉽게 파악할 수 있게 해줍니다. 코드 기반 테스트에 광범위한 주석을 쓸 수는 있는 것은 사실이지만, 그렇게 하는 프로그래머는 거의 없습니다. 많은 사람이 doctest 접근법을 사용하는 것이 훨씬 더 명확한 테스트를 유도한다는 것을 발견했습니다. 어쩌면 단순히 doctest가 설명을 작성하는 것을 코드를 작성하는 것보다 조금 더 쉽게 만들고, 코드에 주석을 쓰는 것이 조금 더 어렵기 때문일 것입니다. 저는 단지 그것보다는 더 깊이 들어간다고 생각합니다: doctest 기반 테스트를 작성할 때의 자연스러운 태도는 소프트웨어의 미세한 포인트를 설명하고 그것을 예제로 보여주는 것입니다. 이것은 자연스럽게 가장 간단한 기능으로 시작하고, 복잡하고 지엽적인 경우까지 논리적으로 진행되는 테스트 파일로 이어집니다. 무작위로 보이는 격리된 기능 조각을 테스트하는 격리된 함수들의 모음 대신에, 일관된 내러티브가 얻어집니다. 이것은 다른 태도이며, 테스트와 설명의 구별을 모호하게 하면서 다른 결과를 낳습니다.

회귀 테스트는 전용 객체나 파일로 제한하는 것이 가장 좋습니다. 테스트 구성을 위한 몇 가지 옵션이 있습니다.:

  • 대화형 예제로 테스트 케이스가 들어있는 텍스트 파일을 작성하고, testfile()이나 DocFileSuite()를 사용하여 파일을 테스트하십시오. doctest를 처음부터 사용하도록 고안된 새로운 프로젝트에서 가장 쉬운 방법이지만, 이 방법을 권장합니다.

  • 명명된 주제에 대한 테스트 케이스를 포함하는 단일 독스트링으로 구성된 _regrtest_topic이라는 함수를 정의하십시오. 이 함수들은 모듈과 같은 파일에 포함되거나 별도의 테스트 파일로 분리될 수 있습니다.

  • 회귀 테스트 주제에서 테스트 케이스가 포함된 독스트링에 대한 __test__ 딕셔너리 매핑을 정의하십시오.

테스트를 모듈에 배치할 때, 모듈 자체가 테스트 실행기가 될 수 있습니다. 테스트가 실패할 때, 문제를 디버깅하는 동안 실패한 doctest 만 다시 실행하도록 테스트 실행기를 조정할 수 있습니다. 다음은 그러한 테스트 실행기의 최소 예입니다:

if __name__ == '__main__':
    import doctest
    flags = doctest.REPORT_NDIFF|doctest.FAIL_FAST
    if len(sys.argv) > 1:
        name = sys.argv[1]
        if name in globals():
            obj = globals()[name]
        else:
            obj = __test__[name]
        doctest.run_docstring_examples(obj, globals(), name=name,
                                       optionflags=flags)
    else:
        fail, total = doctest.testmod(optionflags=flags)
        print("{} failures out of {} tests".format(fail, total))

각주

1

예상 출력과 예외를 모두 포함하는 예제는 지원되지 않습니다. 어디에서 하나가 끝나고 다른 하나가 시작되는지 추측하는 것은 너무 에러가 발생하기 쉽고, 이것은 또한 혼란스러운 테스트를 만들게 됩니다.