Doctest

**doctest**는 파이썬 프로그래밍 언어의 표준 라이브러리에 포함된 모듈로, 표준 파이썬 인터프리터 셸의 출력을 docstring에 복사하여 붙여넣는 방식으로 테스트를 쉽게 생성할 수 있게 해준다.

## 구현 세부 사항

Doctest는 다음과 같은 파이썬의 기능을 혁신적으로 활용한다:
* docstring
* 파이썬 대화형 셸 (명령줄과 내장된 idle 애플리케이션 모두 포함)
* 파이썬 인트로스펙션 (introspection)

파이썬 셸을 사용할 때 기본 프롬프트인  뒤에 새로운 명령이 온다. 보조 프롬프트인 는 명령이 여러 줄로 이어질 때 사용되며, 명령 실행 결과는 다음 줄에 나타날 것으로 기대된다.
빈 줄이나 기본 프롬프트로 시작하는 또 다른 줄은 명령 출력의 끝으로 간주된다.

doctest 모듈은 docstring에서 이러한 프롬프트 시퀀스를 찾아 추출된 명령을 다시 실행하고, 그 출력을 docstring 테스트 예제에 명시된 출력과 비교하여 검사한다.

doctest를 실행할 때의 기본 동작은 테스트를 통과했을 때 아무런 출력도 보여주지 않는 것이다. 이는 doctest 실행 도구의 옵션을 통해 변경할 수 있다. 또한, doctest는 파이썬의 유닛 테스트(unittest) 모듈과 통합되어 있어 doctest를 표준 unittest 테스트 케이스로 실행할 수 있다. Unittest 테스트 케이스 실행 도구를 사용하면 테스트 통과 및 실패와 같은 테스트 통계 보고 등 테스트 실행 시 더 많은 옵션을 사용할 수 있다.

## 리터리트 프로그래밍과 doctest

doctest가 파이썬 프로그램을 서술형 텍스트에 완전히 내장하는 것까지는 허용하지 않지만, 다른 텍스트를 포함할 수 있는 docstring 내에 검증 가능한 예제를 내장하는 것은 가능하다. docstring은 다시 프로그램 파일에서 추출되어 HTML이나 PDF와 같은 다른 형식의 문서를 생성하는 데 사용될 수 있다.
하나의 프로그램 파일에 문서, 테스트, 코드를 모두 포함할 수 있으며 코드에 대해 테스트를 쉽게 검증할 수 있다. 이를 통해 코드, 테스트, 문서를 함께 발전시킬 수 있다.

## 예제를 통한 라이브러리 문서화

Doctest는 API 사용법을 보여줌으로써 라이브러리에 대한 소개를 제공하는 데 매우 적합하다.

파이썬 대화형 인터프리터의 출력을 바탕으로, 라이브러리를 실행하는 테스트와 텍스트를 혼합하여 예상 결과를 보여줄 수 있다.

## 예제

첫 번째 예제는 docstring 내에서 서술형 텍스트와 테스트 가능한 예제가 어떻게 섞일 수 있는지 보여준다.
두 번째 예제에서는 doctest의 더 많은 기능과 그에 대한 설명이 제시된다.
세 번째 예제는 파일이 직접 실행될 때는 파일 내의 모든 doctest를 실행하지만, 모듈로 임포트될 때는 테스트를 실행하지 않도록 설정되어 있다.

### 예제 1: 함수의 docstring에 내장된 doctest

```python
def list_to_0_index(lst):
    """A solution to the problem given in:
    https://rgrig.blogspot.com/2005/11/writing-readable-code.html

    'Given a list, lst, say for each element the 0-index where it appears for
    the first time. So the list x = [0, 1, 4, 2, 4, 1, 0, 2] is
    transformed into y = [0, 1, 2, 3, 2, 1, 0, 3]. Notice that for all
    i we have x[y[i]] = x[i]. Use any programming language and any data
    representation you want.'

    >>> x = [0, 1, 4, 2, 4, 1, 0, 2]
    >>> list_to_0_index(x)
    [0, 1, 2, 3, 2, 1, 0, 3]
    >>>
    """

    return [lst.index(i) for i in lst]
```


### 예제 2: README.txt 파일에 내장된 doctest


```pycon
======================
Demonstration doctests
======================

This is just an example of what a README text looks like that can be used with
the doctest.DocFileSuite() function from Python's doctest module.

Normally, the README file would explain the API of the module, like this:

>>> a = 1
>>> b = 2
>>> a + b
3

Notice, that we just demonstrated how to add two numbers in Python, and
what the result will look like.

A special option allows you to be somewhat fuzzy about your examples:

>>> o = object()
>>> o                 # doctest: +ELLIPSIS
<object object at 0x...>

Exceptions can be tested very nicely too:

>>> x
Traceback (most recent call last):
 ...
NameError: name 'x' is not defined
```


### 예제 3: unique_words.py
이 예제는 파이썬의 StringIO 모듈을 사용하여 파일로부터 함수로의 입력을 시뮬레이션한다.

```python
def unique_words(page):
    """Return set of the unique words in list of lines of text.

    Example:

    >>> from StringIO import StringIO
    >>> fileText = '''the cat sat on the mat
    ... the mat was ondur the cat
    ... one fish two fish red fish
    ... blue fish
    ... This fish has a yellow car
    ... This fish has a yellow star'''
    >>> file = StringIO(fileText)
    >>> page = file.readlines()
    >>> words = unique_words(page)
    >>> print sorted(list(words))
    ["This", "a", "blue", "car", "cat", "fish", "has", "mat",
     "on", "ondur", "one", "red", "sat", "star", "the", "two",
     "was", "yellow"]
    >>>
    """
    return set(word for line in page for word in line.split())

def _test():
    import doctest
    doctest.testmod()

if __name__ == "__main__":
    _test()
```


## Doctest와 문서 생성기

Epydoc의 EpyText 형식과 Docutils의 reStructuredText 형식 모두 docstring 내에서 doctest 섹션의 마크업을 지원한다.

## 다른 프로그래밍 언어에서의 구현

C++에서 doctest 프레임워크는 이 개념을 가장 가깝게 구현한 것이다. 최소한의 오버헤드로 프로덕션 코드에 테스트를 직접 작성할 수 있으며, 바이너리에서 테스트를 제거하는 옵션도 제공한다.

ExUnit.DocTest Elixir 라이브러리는 Doctest와 유사한 기능을 구현한다.

하스켈용 Doctest 구현.

Elm에서 문서 테스트 작성.

러스트에서 문서 테스트 작성.

Elixir에서 문서 테스트 작성.

`byexample`은 마크다운, reStructuredText 및 기타 텍스트 문서 내에서 여러 인기 프로그래밍 언어(예: 파이썬, 루비, 셸, 자바스크립트, C/C++, 자바, Go, 러스트)를 위한 doctest 작성을 지원한다.

## 비판적 의견
개발자에 따라서는 독테스트 doctest를 단위 테스트 unittest처럼 사용하는 데 반대하는 의견도 있다. 독테스트는 주석문자열 docstring 안에 구현되는데, 이 주석문자열은 많은 파이썬 개발 환경에서 툴팁으로 사용된다. 따라서 함수의 사용법에 대해 초심자들이 살펴볼 가능성이 높은데, 문제가 될 수 있는 사용례 50개가 주석문자열에 나타난다면 과연 바람직할 것인가? 라는 주장이 주요한 근거가 되고 있다.

## 같이 보기
* 파이썬
* 소프트웨어 테스트
* 유닛 테스트

## 참고


분류:소프트웨어 테스트
분류:파이썬
분류:소프트웨어 테스트 도구