doctest — 대화형 Python 예제 테스트
doctest — 대화형 Python 예제 테스트
doctest 모듈은 대화형 Python 세션처럼 보이는 텍스트 조각을 검색한 다음, 그 세션을 실행하여 표시된 대로 정확히 동작하는지 검증합니다. doctest를 사용하는 몇 가지 일반적인 방법이 있습니다:
- 모듈의 docstring이 최신 상태인지, 문서화된 대로 모든 대화형 예제가 여전히 동작하는지 검증.
- 테스트 파일이나 테스트 객체의 대화형 예제가 기대대로 동작하는지 검증하는 회귀 테스트.
- 패키지용 튜토리얼 문서를 예제와 함께 풍부하게 작성. 예제와 설명 텍스트 중 어느 쪽을 강조하느냐에 따라 "리터레이트 테스팅(literate testing)" 또는 "실행 가능한 문서(executable documentation)"의 성격을 띱니다.
본문
여기 완전하지만 작은 예제 모듈이 있습니다:
"""
This is the "example" module.
The example module supplies one function, factorial(). For example,
>>> factorial(5)
120
"""
def factorial(n):
"""Return the factorial of n, an exact integer >= 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
"""
import math
if not n >= 0:
raise ValueError("n must be >= 0")
...
return result
if __name__ == "__main__":
import doctest
doctest.testmod()
명령줄에서 example.py를 직접 실행하면 doctest가 동작합니다. 출력이 없는 것은 정상이며, 모든 예제가 동작했다는 뜻입니다. -v를 전달하면 doctest가 시도한 내용의 상세 로그와 끝의 요약을 출력합니다.
docstring의 예제 확인
모듈 M의 끝에 if __name__ == "__main__": import doctest; doctest.testmod()를 추가하는 것이 시작하는 가장 간단한 방법입니다. testmod()로 verbose=True를 전달해 상세 모드를 강제하거나 verbose=False로 금지할 수 있습니다. testfile() 함수로 텍스트 파일의 대화형 예제를 테스트할 수도 있습니다.
명령줄 사용법
doctest 모듈은 명령줄에서 스크립트로 호출할 수 있습니다:
python -m doctest [-v] [-o OPTION] [-f] file [file ...]
-v,--verbose— 시도한 모든 예제의 상세 보고서와 끝의 요약을 출력합니다.-o,--option <option>— 옵션 플래그가 doctest의 다양한 동작을 제어합니다 (3.4에서 추가).-f,--fail-fast—-oFAIL_FAST의 단축형입니다 (3.4에서 추가).
파일 이름이 .py로 끝나지 않으면 doctest는 testfile()로 실행해야 한다고 추론합니다.
동작 방식
어떤 docstring이 검사되는가: 모듈 docstring과 모든 함수·클래스·메서드 docstring이 검색됩니다. 모듈로 import된 객체는 검색되지 않습니다. 테스트가 help 텍스트의 일부가 아니어야 하는 경우 __test__라는 모듈 수준 변수를 사용할 수 있습니다. M.__test__는 딕셔너리여야 하며 각 항목이 (문자열) 이름을 함수 객체·클래스 객체·문자열에 매핑합니다.
docstring 예제는 어떻게 인식되는가: >>> 프롬프트로 시작하는 코드 줄과 그 뒤의 예상 출력이 인식됩니다. 예상 출력에는 모두-공백 줄이 포함될 수 없는데, 그러한 줄은 예상 출력의 끝을 알리는 신호로 간주되기 때문입니다. 예상 출력에 빈 줄이 필요하면 <BLANKLINE>을 넣습니다. 하드 탭은 8열 탭 정지로 공백으로 확장됩니다. stdout 출력은 캡처되지만 stderr 출력은 아닙니다(예외 트레이스백은 다른 수단으로 캡처됨).
실행 컨텍스트: 예제는 각각 별도로 실행되며, 일반적으로 testmod()는 모듈의 전역 네임스페이스에서 실행합니다.
예외는 어떻게 처리되는가: Traceback (most recent call last):와 ... 다음에 예외 타입과 메시지가 오는 형태로 트레이스백이 캡처됩니다.
옵션 플래그와 지시어: NORMALIZE_WHITESPACE, ELLIPSIS, IGNORE_EXCEPTION_DETAIL 등 다양한 옵션 플래그가 doctest 동작을 제어하며, # doctest: +OPTION 지시어로 예제별로 적용할 수 있습니다.
주요 객체
DocTestFinder— 주어진 객체에 관련된DocTest를 docstring에서 추출하는 처리 클래스. 모듈, 클래스, 함수, 메서드에서 DocTest를 추출할 수 있습니다.DocTestParser— docstring을 DocTest로 파싱합니다.DocTestRunner— DocTest를 실행하고 결과를 검증합니다.TestResults— 테스트 결과 객체.
doctest는 표준 Python 테스트 스위트와 라이브러리에 많은 예제가 있으며, 특히 Lib/test/test_doctest/test_doctest.py에서 유용한 예제를 찾을 수 있습니다.