doctest --- 一个改善python代码质量的工具

简介python

  说实话吧,以前一直没有怎么重视给本身的代码加上测试逻辑;也就是说我只是写了代码,可是并无给本身的代码加上测试代码;linux

  整个过程就是写完后本身测试一下,看一下跑出来的结果是正确的就心满意足了。过一段时间以后老是对本身的代码有一种陌生感,算法

  就算有无缺的注释,我也不能100%保证它的功能上是OK的。sql

 

  一方面是对于功能上的细节我已经忘记的差很少了,另外一方面就算是有注释我也要看上一会才能回想起本身当初是怎么想的,大声框架

  的说出个人代码没有问题确实是一件比较难的事。函数

 

给本身的代码加上测试代码的必要性单元测试

  一、一种态度问题,就我如今而言不给本身的代码加上测试代码是对质量的不负责任;我但愿本身尽量的生成出没有Bug的代码测试

  然而给代码加上测试代码就是一个比较好的解决方案spa

 

  二、虽然给代码加上测试代码会用到更多的人天,可是对于一个大点的项目来讲它更加的可按;也就是说当我改动现有代码或增长code

  新的功能的时候是否是会引起bug,咱们只要跑一遍测试用例,若是测试用例都能经过那么说明是OK的,若是有用例没有经过这个

  时候开发人员就能够本身查了,不用等到测试发现以后再报给咱们。

 

  三、总的来讲给本身的代码加上测试代码,这会使我对本身的 代码|项目 更加的放心

 

doctest模块的功能

  doctest模块会读取python代码中的文档字符串,并按文档字符串中的内容来运行测试逻辑;那咱们的测试逻辑怎么加到文档字符串

  中去呢?这个doctest已经帮咱们想好了,开发工程师只要把python交互式下的内容写入到文档字符串中就好了。

 

doctest使用举例

  一个简单的选择排序算法为例子

def select_sort(lst):
    """
    选择排序算法
    """
    for i in range(0,len(lst)):
        min_item_index = i
        for j in range(i,len(lst)):
            if lst[j] < lst[min_item_index]:
                min_item_index = j
        if min_item_index != i:
            lst[min_item_index],lst[i] = lst[i],lst[min_item_index]

  

  能够看到的代码只提供了一个简单的文档字符串,用来讲明了一下这个函数的做用。那咱们怎么给这个方法加上测试代码呢?

  事实上这个就是从简单的手工测试(工程师本身在python交互式模式下测试本身的代码)演化而来的,假设工程是在交互模式下

  测试了三个用例

>>> from selectsort import select_sort
>>> lst = [3,2,1,4,5,6,-1]
>>> select_sort(lst)
>>> lst
[-1, 1, 2, 3, 4, 5, 6]
>>> 
>>> lst = [2,1]
>>> select_sort(lst)
>>> lst
[1, 2]
>>> 
>>> lst = [0]
>>> select_sort(lst)
>>> lst
[0]

  

  doctest只要求咱们把复制到文件字符串中就好了,固然啦仍是另外加两行代码不过这个是死的,记下来就是了

def select_sort(lst):
    """
    选择排序算法

    >>> lst = [3,2,1,4,5,6,-1]
    >>> select_sort(lst)
    >>> lst
    [-1, 1, 2, 3, 4, 5, 6]
    >>> 
    >>> lst = [2,1]
    >>> select_sort(lst)
    >>> lst
    [1, 2]
    >>> 
    >>> lst = [0]
    >>> select_sort(lst)
    >>> lst
    [0]
    """
    for i in range(0,len(lst)):
        min_item_index = i
        for j in range(i,len(lst)):
            if lst[j] < lst[min_item_index]:
                min_item_index = j
        if min_item_index != i:
            lst[min_item_index],lst[i] = lst[i],lst[min_item_index]


if __name__ == "__main__":
    import doctest
    doctest.testmod()

 

  能够看到最后三行表示当咱们单独运行这个文件的时候就执行测试,那我测试下看看

python3 selectsort.py -v
Trying:
    lst = [3,2,1,4,5,6,-1]
Expecting nothing
ok
Trying:
    select_sort(lst)
Expecting nothing
ok
Trying:
    lst
Expecting:
    [-1, 1, 2, 3, 4, 5, 6]
ok
Trying:
    lst = [2,1]
Expecting nothing
ok
Trying:
    select_sort(lst)
Expecting nothing
ok
Trying:
    lst
Expecting:
    [1, 2]
ok
Trying:
    lst = [0]
Expecting nothing
ok
Trying:
    select_sort(lst)
Expecting nothing
ok
Trying:
    lst
Expecting:
    [0]
ok
1 items had no tests:
    __main__
1 items passed all tests:
   9 tests in __main__.select_sort
9 tests in 2 items.
9 passed and 0 failed.
Test passed.

  

  最后一行的 "Test passed" 表示测试经过了,之因此有这么多输出是由于咱们加了 -v 参数,不加这个的话就是真正的linux哲学了

  “没有输出就是最好的输出”

yifengliu-nb:sorts jianglexing$ python3 selectsort.py 
yifengliu-nb:sorts jianglexing$ 
yifengliu-nb:sorts jianglexing$ 

 

总结

  python中还有一个专门用于单元测试的unittest框架,这个相比doctest来讲要强大很多,一次再说吧!

      https://www.sqlpy.com

 

---

相关文章
相关标签/搜索