맨위로가기

Doctest

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

Doctest는 파이썬의 docstring, 대화형 셸, 내부 검사 기능을 활용하여 코드의 정확성을 검증하고 문서화하는 도구이다. 함수 docstring 내에 예제 코드를 작성하거나, 외부 텍스트 파일에 예제를 포함하여 테스트를 수행할 수 있으며, 테스트가 통과하면 출력이 표시되지 않고, 실패 시 오류를 보고한다. Doctest는 문서화와 테스트를 통합하여 코드의 가독성과 유지보수성을 높이지만, 복잡한 테스트 시나리오에는 한계가 있으며, 테스트 코드와 실제 코드의 혼재에 대한 비판도 존재한다. Doctest의 개념은 C++, Elixir, Haskell, Elm, Rust 등 다른 프로그래밍 언어에서도 구현되어 사용되고 있다.

더 읽어볼만한 페이지

  • 소프트웨어 테스트 도구 - Valgrind
    Valgrind는 동적 분석 도구들의 프레임워크로, 가상 머신 기반으로 작동하며 메모리 오류 감지, 멀티스레드 코드 분석 등 다양한 기능을 제공하지만, 정적 또는 스택 할당 데이터의 경계 오류는 모두 감지하지 못한다.
  • 소프트웨어 테스트 도구 - 코드 커버리지
    코드 커버리지는 테스트 스위트에 의해 실행된 코드의 비율을 측정하는 기준으로, 최종 제품 인증에 필요한 테스트 수준을 결정하며, 다양한 커버리지 기준 중 안전 필수 애플리케이션에서는 수정 조건/결정 커버리지(MC/DC)와 같은 고급 기준이 사용된다.
  • 파이썬 - 귀도 반 로섬
    귀도 반 로섬은 네덜란드 출신의 프로그래머로, 1989년 크리스마스 기간에 취미로 파이썬 프로그래밍 언어를 개발했으며, 구글과 드롭박스 등에서 일하다 2020년 마이크로소프트에 수석 엔지니어로 합류했다.
  • 파이썬 - 모조 (프로그래밍 언어)
    모조는 모듈러사에서 개발한 파이썬과 유사한 구문의 고성능 프로그래밍 언어로, AI 애플리케이션 개발에 초점을 맞추고 러스트의 영향을 받은 메모리 안전성을 제공하며 향후 오픈 소스로 전환될 예정이다.
  • 소프트웨어 테스트 - 보안 취약점
    보안 취약점은 시스템의 설계, 구현, 운영, 관리상 결함이나 약점으로, 위협에 의해 악용되어 시스템 보안 정책을 위반할 수 있는 요소이며, ISO 27005, IETF RFC 4949, NIST SP 800-30, ENISA 등 다양한 기관에서 정의하고 있다.
  • 소프트웨어 테스트 - A/B 테스트
    A/B 테스트는 두 가지 이상의 대안을 비교하여 더 나은 성과를 판단하는 방법으로, 웹사이트, 애플리케이션 등 다양한 분야에서 사용자 인터페이스 등을 테스트하며 통계적 가설 검정을 기반으로 한다.
Doctest

2. 기본 개념 및 사용법

Doctest는 docstring과 파이썬 대화형 셸(명령줄 및 IDLE)의 기능을 활용하여 테스트를 수행하는 모듈이다.[1][2] Doctest는 기본적으로 테스트가 통과하면 출력을 표시하지 않지만, 실행 옵션을 통해 결과를 표시하도록 수정할 수 있다. 또한, 파이썬 유닛 테스트 모듈과 통합되어 표준 unittest 테스트 케이스로 doctest를 실행할 수 있으며, 이 경우 더 많은 실행 옵션과 통계 보고를 활용할 수 있다.

2. 1. Docstring 활용

함수의 docstring 내에 파이썬 인터프리터 형식의 예제 코드를 작성하고, Doctest는 이를 실행하여 예상 결과와 비교한다.[1][2] `>>>` 프롬프트를 사용하여 코드를 입력하고, 다음 줄에 예상되는 결과를 작성한다. 여러 줄에 걸친 코드는 `...` 프롬프트를 사용한다.

Doctest는 다음과 같은 파이썬 기능을 활용한다.[1][2]

  • docstring
  • 파이썬 대화형 셸 (명령줄과 포함된 IDLE 애플리케이션 모두)
  • 파이썬 내부 검사


파이썬 셸을 사용할 때, 기본 프롬프트는 `>>>`이며, 그 뒤에 새로운 명령어가 온다. 보조 프롬프트 `...`는 여러 줄에 걸쳐 명령어를 계속할 때 사용된다. 그리고 명령 실행 결과는 다음 줄에 표시될 것으로 예상된다. 빈 줄이나 기본 프롬프트로 시작하는 다른 줄은 명령어의 출력 종료로 간주된다.

doctest 모듈은 docstring에서 이러한 프롬프트 시퀀스를 찾아서, 추출된 명령어를 다시 실행하고 docstring 테스트 예제에 주어진 명령어의 출력과 결과를 비교한다.

다음은 `list_to_0_index` 함수의 docstring 예시이다.



def list_to_0_index(lst):

"""다음에 주어진 문제에 대한 해결책:

https://rgrig.blogspot.com/2005/11/writing-readable-code.html

'리스트 lst가 주어졌을 때, 각 요소가 처음 나타나는 0-인덱스를 구하라.

예를 들어, 리스트 x = [0, 1, 4, 2, 4, 1, 0, 2]는

y = [0, 1, 2, 3, 2, 1, 0, 3]으로 변환된다. 모든 i에 대해 x[y[i]] = x[i]임을

알아두자. 어떤 프로그래밍 언어와 데이터 표현 방식을 사용해도 좋다.'

>>> 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. 2. 외부 파일 활용

`README.txt`와 같은 별도의 텍스트 파일에도 파이썬 인터프리터 형식의 예제를 작성하여 테스트를 수행할 수 있다. `doctest.testfile()` 함수를 사용하여 외부 파일을 지정한다.[1]

다음은 `README.txt` 파일의 예시이다.

```text

내 프로젝트에 오신 것을 환영합니다!

이 프로젝트는 숫자의 제곱을 계산하는 간단한 함수를 제공합니다.

예를 들어:

>>> square(2)

4

>>> square(3.0)

9.0

>>> square(-2)

4

```

`doctest`는 이 파일을 분석하여 ">>> " 접두사를 찾고, 해당 라인들을 파이썬 인터프리터에 입력된 것처럼 처리한다.[1]

다음은 테스트를 실행하는 파이썬 코드이다.

```python

import doctest

import math

def square(x):

"""

x의 제곱을 반환합니다.

>>> square(2)

4

>>> square(3.0)

9.0

>>> square(-2)

4

>>> square(0)

0

"""

return x * x

if __name__ == "__main__":

doctest.testfile("README.txt")

```

위 코드를 실행하면 `README.txt` 파일 내의 예제들을 테스트하고, 결과에 따라 오류를 출력하거나 테스트 통과를 알린다.[1]

2. 3. 실행 및 결과

`doctest.testmod()` 함수를 사용하여 현재 모듈의 `docstring`에 포함된 테스트를 실행한다. 테스트가 성공하면 기본적으로 아무런 출력이 없으며, 실패할 경우 상세한 오류 메시지가 출력된다.[1][2] `verbose = True` 옵션을 통해 실행 결과를 상세히 확인할 수 있다.

3. 활용 사례

Doctest는 라이브러리의 API 사용법을 예제와 함께 문서화하는 데 효과적이다.[1] 파이썬 대화형 인터프리터의 출력을 기반으로, 라이브러리 사용 테스트와 예상 결과를 텍스트로 함께 보여준다.[1] 코드, 테스트, 문서가 함께 발전하도록 돕는다.[1]

Doctest는 프로그램 파일에서 코드, 테스트, 문서를 추출하여 검증 가능한 테스트를 만든다.[1] docstring은 HTML, PDF 등 다른 형식의 문서를 생성하기 위해 프로그램 파일에서 추출할 수 있다.[1]

3. 1. 예제 1: 함수 docstring 내 Doctest

python

def list_to_0_index(lst):

"""아래 링크에 주어진 문제에 대한 답이다.

https://rgrig.blogspot.com/2005/11/writing-readable-code.html

'어떤 리스트 lst가 주어졌을 때, 각 요소가 처음 나타나는 인덱스를 구하라.

그래서 리스트 x = [0, 1, 4, 2, 4, 1, 0, 2]는 y = [0, 1, 2, 3, 2, 1, 0, 3]로 변환된다.

모든 i에 대해 x[y[i]] = x[i]이다. 프로그래밍 언어와 데이터 표현 형식은 원하는대로 선택하라'

>>> 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]

def _test():

import doctest

doctest.testmod(verbose = True)

if "__main__" == __name__ :

_test()

```

예시 1은 문서 문자열(docstring)에서 테스트 가능한 예시와 서술 텍스트를 어떻게 함께 사용할 수 있는지 보여준다.

```python

def list_to_0_index(lst):

"""다음에 주어진 문제에 대한 해결책:

https://rgrig.blogspot.com/2005/11/writing-readable-code.html

'리스트 lst가 주어졌을 때, 각 요소가 처음 나타나는 0-인덱스를 구하라.

예를 들어, 리스트 x = [0, 1, 4, 2, 4, 1, 0, 2]는

y = [0, 1, 2, 3, 2, 1, 0, 3]으로 변환된다. 모든 i에 대해 x[y[i]] = x[i]임을

알아두자. 어떤 프로그래밍 언어와 데이터 표현 방식을 사용해도 좋다.'

>>> 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]

3. 2. 예제 2: README.txt 파일 내 Doctest

프로젝트의 `README.txt` 파일에 사용 예제를 작성하고, 이를 Doctest로 실행하여 문서와 테스트를 통합할 수 있다.

다음은 `README.txt` 파일의 예시이다.

```text

내 프로젝트에 오신 것을 환영합니다!

이 프로젝트는 숫자의 제곱을 계산하는 간단한 함수를 제공합니다.

예를 들어:

>>> square(2)

4

>>> square(3.0)

9.0

>>> square(-2)

4

```

Doctest를 실행하면, `doctest`는 이 파일을 분석하여 ">>> " 접두사를 찾고, 해당 라인들을 파이썬 인터프리터에 입력된 것처럼 처리한다.

다음은 테스트를 실행하는 파이썬 코드이다.

```python

import doctest

import math

def square(x):

"""

x의 제곱을 반환합니다.

>>> square(2)

4

>>> square(3.0)

9.0

>>> square(-2)

4

>>> square(0)

0

"""

return x * x

if __name__ == "__main__":

doctest.testfile("README.txt")

```

이 코드를 실행하면 다음과 같은 출력이 나타난다.

```text
**

File "README.txt", line 4, in README.txt

Failed example:

square(2)

Expected:

4

Got:

1
**

1 items had failures.

0 tests in 1 items.

1 failures in 1 tests.

```

`README.txt`의 첫 번째 테스트("예를 들어:" 섹션의 첫 번째 테스트)가 실패했기 때문에 오류가 발생한다. 테스트를 수정하도록 파일을 편집하면 모든 테스트를 통과한다.

3. 3. 예제 3: StringIO 모듈 활용

python

def unique_words(page):

"""텍스트 줄 목록에서 고유한 단어의 집합을 반환합니다.

예시:

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

```

이 예제는 StringIO 모듈을 사용하여 파일 입력을 시뮬레이션하고, Doctest를 통해 함수를 검증합니다. 파일 실행 시 파일 내의 모든 doctest를 실행하지만, 모듈로 가져올 때는 테스트를 실행하지 않습니다.[1]

4. 장점 및 한계

Doctest는 코드와 함께 테스트 케이스를 작성하므로, 코드 변경 시 테스트를 쉽게 업데이트할 수 있고, 별도의 테스트 프레임워크 없이 파이썬 기본 문법만으로 테스트를 작성할 수 있다는 장점이 있다.[10] 또한 예제 코드를 통해 함수의 사용법을 명확하게 보여줄 수 있다. 그러나 일부 개발자들은 Doctest를 단위 테스트처럼 사용하는 것에 반대한다. Doctest는 주석 문자열(docstring) 안에 구현되는데, 이는 많은 파이썬 개발 환경에서 툴팁으로 사용된다.[10] 따라서 초심자가 함수의 사용법을 보기 위해 툴팁을 확인했을 때, 복잡한 Doctest 코드가 나타나면 가독성을 해칠 수 있다는 우려가 있다.[10]

4. 1. 장점

Doctest는 코드와 함께 테스트 케이스를 작성하므로, 코드 변경 시 테스트를 쉽게 업데이트할 수 있다는 장점이 있다. 예제 코드를 통해 함수의 사용법을 명확하게 보여줄 수 있으며, 별도의 테스트 프레임워크를 학습할 필요 없이 파이썬 기본 문법만으로 테스트를 작성할 수 있다.[10]

프로그램 파일은 코드, 테스트, 문서를 포함할 수 있으며, 코드에 대해 쉽게 검증할 수 있는 테스트 또한 포함할 수 있다. 이를 통해 코드, 테스트, 문서가 함께 발전할 수 있다.

4. 2. 한계

Doctest는 단위 테스트처럼 사용하기에는 한계가 있다는 의견이 있다. Doctest는 주석 문자열(docstring) 안에 구현되는데, 이 주석 문자열은 많은 파이썬 개발 환경에서 툴팁으로 사용된다.[10] 따라서 함수의 사용법을 처음 접하는 사람들이 툴팁을 통해 Doctest를 볼 가능성이 높은데, 만약 50개의 문제가 될 수 있는 사용 예시가 주석 문자열에 나타난다면 가독성을 해칠 수 있다는 비판이 있다.[10]

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

Doctest의 개념은 다른 프로그래밍 언어에도 영향을 미쳤다. C++, 엘릭서, 하스켈, 엘름, 러스트 등 다양한 언어에서 Doctest와 유사한 기능을 구현하거나 문서 테스트를 지원한다.

5. 1. C++, Elixir, Haskell, Elm, Rust

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

엘릭서의 ExUnit.DocTest 라이브러리는 Doctest와 유사한 기능을 구현한다.[4][8]

하스켈에도 Doctest 구현이 존재한다.[5]

엘름과 러스트에서도 문서 테스트 작성을 지원한다.[6][7]

byexample[9]마크다운, reStructuredText 등 여러 텍스트 문서 내에서 Python, Ruby, Shell, JavaScript, C/C++, Java, Go, Rust 등 다양한 프로그래밍 언어에 대한 doctest 작성을 지원한다.

6. 결론

일부 개발자들은 doctest를 단위 테스트처럼 사용하는 것에 반대한다. Doctest는 주석 문자열(docstring) 안에 구현되는데, 이 주석 문자열은 많은 파이썬 개발 환경에서 툴팁으로 사용된다.[10] 따라서 함수의 사용법에 대해 초심자들이 살펴볼 가능성이 높은데, 문제가 될 수 있는 사용례 50개가 주석 문자열에 나타난다면 바람직하지 않다는 주장이 제기된다.

참조

[1] 웹사이트 doctest — Test interactive Python examples https://docs.python.[...]
[2] 웹사이트 "[LONG] docstring-driven testing" https://groups.googl[...] 2024-07-16
[3] 웹사이트 doctest/doctest https://github.com/d[...] 2024-07-16
[4] 웹사이트 ExUnit.DocTest — ExUnit v1.17.2 https://hexdocs.pm/e[...] 2024-07-16
[5] 웹사이트 sol/doctest https://github.com/s[...] 2024-07-16
[6] 웹사이트 tshm/elm-doctest https://github.com/t[...] 2024-07-16
[7] 웹사이트 Testing https://doc.rust-lan[...] 2024-07-16
[8] 웹사이트 Doctests, patterns, and with — Elixir v1.17.2 https://hexdocs.pm/e[...] 2024-07-16
[9] 웹사이트 byexample https://byexamples.g[...] 2024-07-16
[10] 웹인용 처음만나는 파이썬 프로그래밍 http://juehan.github[...] 2012-11-18



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com