前言
之前簡單的按照教程打過一遍doctest
模塊笼恰,但是并未重視踊沸,再加上自己平常就不用測試案例,所以最近在一本書上再看到這個模塊時心里又有些模糊淡忘了社证。所以這次專門做個筆記逼龟,關(guān)于doctest
模塊以及稍微提及下unittest
。
我們?yōu)槭裁春鲆?/h3>
少廢話追葡,直接看我得日常操作(或許也是大部分人的操作)就能得到原因腺律。
""" Fibonacci Module """
def fib(n):
""" Calculates the n-th Fibonacci number iteratively """
a, b = 0, 1
for i in range(n):
a, b = b, a + b
return a
def fiblist(n):
""" creates a list of Fibonacci numbers up to the n-th generation """
fib = [0,1]
for i in range(1,n):
fib += [fib[-1]+fib[-2]]
return fib
上面是一個斐波那契數(shù)列的日常實現(xiàn)。
而我們經(jīng)常直接就這么干了(手動測試)宜肉,這里手動斜眼:
>>> from fibonacci import fib, fiblist
>>> fib(0)
0
>>> fib(1)
1
>>> fib(10)
55
>>> fiblist(10)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> fiblist(-8)
[0, 1]
>>> fib(-1)
0
>>> fib(0.5)
Traceback (most recent call last):
File "", line 1, in
File "fibonacci.py", line 6, in fib
for i in range(n):
TypeError: 'float' object cannot be interpreted as an integer
>>>
知道憑感覺想到了匀钧,輸入一個浮點數(shù)會報錯。
又或者我們會寫一個簡單判斷測試一下谬返,比如我們在文件中加入下面代碼:
if __name__ == "__main__":
if fib(0) == 0 and fib(10) == 55 and fib(50) == 12586269025:
print("Test for the fib function was successful!")
else:
print("The fib function is returning wrong values!")
# 運行一下
$ python3 fibonacci.py
Test for the fib function was successful!
如果函數(shù)沒有得到我們事先算好的值之斯,返回"The fib function is returning wrong values!
所以結(jié)論是:doctest
好像用不太到啊,我們像上面那么干就夠了啊~~
doctest模塊
什么情況下用doctest
:
正式項目的測試或者需要優(yōu)雅的方式遣铝,讓逼格變高的測試案例佑刷。
一般有以下因素時盡量要試用下:
- 大小
對于集合(string,list,tuple,dict)- 空集合
- 單元素集
- 最少數(shù)量用例
- 較多用例
- 對分
- 奇數(shù)/偶數(shù)
- 正/負(fù)
- 空/滿
- 邊界
函數(shù)在接近閾值的時候處理不同,測試閾值酿炸。 - 順序
函數(shù)對不同順序的輸入值瘫絮,測試不同的順序。
所以我們可以這么寫
import doctest
def fib(n):
"""
Calculates the n-th Fibonacci number iteratively
>>> fib(0)
0
>>> fib(1)
1
>>> fib(10) #正確值為55
56
>>> fib(15)
610
>>>
"""
a, b = 0, 1
for i in range(n):
a, b = b, a + b
return a
if __name__ == "__main__":
doctest.testmod(verbose=True)
之后$ python3 fibonacci_doctest.py
可得到測試信息填硕,verbose=True
為測試通過與未通過都將消息顯示出來,默認(rèn)為False麦萤,只顯示失敗信息。
Trying:
fib(0)
Expecting:
0
ok
Trying:
fib(1)
Expecting:
1
ok
Trying:
fib(10)
Expecting:
56
**********************************************************************
File "fibonacci_doctest.py", line 11, in __main__.fib
Failed example:
fib(10)
Expected:
56
Got:
55
Trying:
fib(15)
Expecting:
610
ok
1 items had no tests:
__main__
**********************************************************************
1 items had failures:
1 of 4 in __main__.fib
4 tests in 2 items.
3 passed and 1 failed.
***Test Failed*** 1 failures.
也有可能你需要在if __name__ == "__main__":
下面寫其他函數(shù)而不是測試函數(shù)扁眯。你可以換個方式频鉴。我修改下主函數(shù)。
if __name__ == "__main__":
print('hello world')
之后$ python3 -m doctest -v fibonacci_doctest.py
跟上面測試信息一樣恋拍,并不會輸出hello world
,這里-v等同verbose參數(shù)藕甩。
是否需要unittest
unittest是一個單元測試框架施敢,具體教程可去官方文檔查詢,這里不多做介紹狭莱。
有些人用unittest多余doctest僵娃,主要原因是我把測試內(nèi)容寫在函數(shù)中,像函數(shù)注釋一樣腋妙,一旦測試的東西一多默怨,那么可能導(dǎo)致函數(shù)看上去很復(fù)雜,影響美觀骤素,導(dǎo)致不優(yōu)雅匙睹。
但是doctest還有個testfile
方法愚屁,將測試文檔寫入一個單獨的文件。這里我寫一下痕檬。
# 盡量與py文件同名或者相近霎槐,好辨認(rèn),然后以txt結(jié)尾
The ``fibonacci_doctest`` module
======================
Using ``fib``
-------------------
First import fib fuction
>>> from fibonacci_doctest import fib
Now use it
>>> fib(0)
0
>>> fib(1)
1
>>> fib(10) #正確值為55
56
>>> fib(15)
610
# 上面時文件所有內(nèi)容梦谜,及其一些注釋丘跌,最重要的是 >>>后面的內(nèi)容為測試內(nèi)容
然后我們在fibonacci_doctest.py
中主函數(shù)中寫入:
if __name__ == "__main__":
doctest.testfile("fibonacci_doctest.txt")
得到如下:
**********************************************************************
File "fibonacci_doctest.txt", line 16, in fibonacci_doctest.txt
Failed example:
fib(10) #正確值為55
Expected:
56
Got:
55
**********************************************************************
1 items had failures:
1 of 5 in fibonacci_doctest.txt
***Test Failed*** 1 failures.
OK,結(jié)束唁桩。很好用闭树。
總結(jié)
doctest
測試模塊時比較基礎(chǔ),容易理解也容易使用荒澡。
之前看見一個大佬說過报辱,大體意思是這樣的:你寫完一個函數(shù),心里就已經(jīng)想好了測試案例仰猖,各種測試因素捏肢,來驗證你寫的這個函數(shù)的準(zhǔn)確性。
說的很對饥侵。
參考資料
https://www.python-course.eu/python3_tests.php
http://blog.csdn.net/u012151283/article/details/77511806
https://docs.python.org/3/library/doctest.html#doctest.testfile