Doctest
doctest는 파이썬 프로그래밍 언어의 표준 라이브러리에 포함된 모듈로, 표준 파이썬 인터프리터 셸의 출력을 docstring에 복사하여 붙여넣는 방식으로 테스트를 쉽게 생성할 수 있게 해준다.
구현 세부 사항
Doctest는 다음과 같은 파이썬의 기능을 혁신적으로[1] 활용한다:[2]
- 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
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
======================
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 모듈을 사용하여 파일로부터 함수로의 입력을 시뮬레이션한다.
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 프레임워크는 이 개념을 가장 가깝게 구현한 것이다. 최소한의 오버헤드로 프로덕션 코드에 테스트를 직접 작성할 수 있으며, 바이너리에서 테스트를 제거하는 옵션도 제공한다.[3]
ExUnit.DocTest Elixir 라이브러리는 Doctest와 유사한 기능을 구현한다.[4]
byexample[9]은 마크다운, reStructuredText 및 기타 텍스트 문서 내에서 여러 인기 프로그래밍 언어(예: 파이썬, 루비, 셸, 자바스크립트, C/C++, 자바, Go, 러스트)를 위한 doctest 작성을 지원한다.
비판적 의견
개발자에 따라서는 독테스트 doctest를 단위 테스트 unittest처럼 사용하는 데 반대하는 의견도 있다. 독테스트는 주석문자열 docstring 안에 구현되는데, 이 주석문자열은 많은 파이썬 개발 환경에서 툴팁으로 사용된다.[10] 따라서 함수의 사용법에 대해 초심자들이 살펴볼 가능성이 높은데, 문제가 될 수 있는 사용례 50개가 주석문자열에 나타난다면 과연 바람직할 것인가? 라는 주장이 주요한 근거가 되고 있다.
같이 보기
참고
- ↑ “doctest — Test interactive Python examples” (영어). 《Python documentation》. 2024년 7월 15일에 원본 문서에서 보존된 문서.
- ↑ “[LONG] docstring-driven testing”. 《groups.google.com》. 2022년 10월 2일에 원본 문서에서 보존된 문서. 2024년 7월 16일에 확인함.
- ↑ “doctest/doctest”. 2024년 7월 15일. 2024년 7월 16일에 확인함 – GitHub 경유.
- ↑ “ExUnit.DocTest — ExUnit v1.17.2”. 《hexdocs.pm》. 2024년 7월 16일에 확인함.
- ↑ “sol/doctest”. 2024년 7월 16일. 2024년 5월 31일에 원본 문서에서 보존된 문서. 2024년 7월 16일에 확인함 – GitHub 경유.
- ↑ “tshm/elm-doctest”. 2023년 4월 5일. 2023년 3월 7일에 원본 문서에서 보존된 문서. 2024년 7월 16일에 확인함 – GitHub 경유.
- ↑ “Testing”. 《doc.rust-lang.org》. 2024년 1월 5일에 원본 문서에서 보존된 문서. 2024년 7월 16일에 확인함.
- ↑ “Doctests, patterns, and with — Elixir v1.17.2”. 《hexdocs.pm》. 2024년 7월 16일에 확인함.
- ↑ “byexample” (미국 영어). 《byexample》. 2023년 5월 27일에 원본 문서에서 보존된 문서. 2024년 7월 16일에 확인함.
- ↑ “처음만나는 파이썬 프로그래밍”. 2013년 3월 18일에 원본 문서에서 보존된 문서. 2012년 11월 18일에 확인함.
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.