专栏首页未闻CodePython的单元测试(一)

Python的单元测试(一)

测试驱动的软件开发方式可以强迫程序员在开发程序的时候使程序的函数之间实现高内聚,低耦合。这样的方式可以降低函数之间的依赖性,方便后续的修改,增加功能和维护。

一个函数高内聚,就是指这个函数专注于实现单一的任务,不会做除了生产这个任务以外的其他事情。可以想象一个人,他把自己关在一个小房子里面生产东西,只留两扇窗户,他需要什么材料,你就从小窗户给他送进去(参数),他做好了东西,就给你从另一个窗户里面送出来(return),他不会说,我要生产一个轮子,但是我首先需要一个女人进来,他不会说,这是计划的一部分。

几个函数是低耦合的,就是指他们的依赖性小。他们就像是葫芦娃,每个都有自己独特的能力,可以自己单干,在关键的时候还可以合体,变成小金刚。他们就像积木一样,各有各的功能,需要使用的时候直接组合在一起就可以了。

使用测试驱动开发,每一个测试只测试一个功能,这样就可以迫使函数把自己独立出来,尽量减少和其他函数的依赖。

例如,有一个文件1.txt,他的内容是两个数字,使用逗号隔开。形如“2,4”(不包括外侧双引号,下同)。我要写一个程序readandadd.py,读取硬盘上的1.txt文件,然后把这个文件的内容打印到屏幕上。

不规范的写法一:

    f= open('1.txt','r')
    b = f.read().split(',')
    f.close()
    print int(b[0])+int(b[1])

不规范写法二:

    def A():
        f= open('1.txt','r')
        b = f.read().split(',')
        f.close()
        print int(b[0])+int(b[1])
    A()

比较规范的写法:

    def read(filename):
        f= open(filename,'r')
        info = f.read()
        f.close()
        return info

    def getnum(info):
        twonum = info.split(',')
        return twonum

    def addnum(twonum):
        return int(twonum[0])+int(twonum[1])

    if __name__ == '__main__':
            info = read('1.txt')
            twonum = getnum(info)
            result = addnum(twonum)
            print result

这样写的好处是,如果想测试读文件的功能,就只需要测试read()函数,如果想测试把两个数分开的功能,就只需要测试getnum()函数。而相反,在不规范写法二中,虽然只想测试两个数字相加的功能,可是却不得不首先打开文件并读取文件然后把数字分开。

继续回到比较规范的写法当中,我相信很多人写完read()函数以后,肯定会输入如下代码:

    def read(filename):
        f= open(filename,'r')
        info = f.read()
        f.close()
        return info

    print read('1.txt')

然后运行程序,发现正常打印出’2,3’以后,再开始写getnum()函数。写完getnum以后,测试getnum()函数没问题以后再开始写然后测试addnum()函数。最后测试整个程序的功能。

其实这个过程,已经就是在做单元测试了。然而这样操作的弊端是什么?如果整体程序已经写好了,之前做测试点代码也就删除了。那么如果突然把程序做了修改。例如1.txt里面数字的分隔从1个逗号变成了空格,或者变成了3个数字,那必然要修改getnum(),但是又如何测试修改的部分呢?还要把不相干的代码给注释掉。不仅麻烦,而且容易出错。

现在,把测试的代码单独独立出来。会有什么效果呢?尝试创建一个test.py程序,代码如下:

    import readandadd

    def testread():
        print 'read:',readandadd.read('1.txt')

    def testgetnum():
        print 'getnum:',readandadd.getnum('2,3')

    def testaddnum():
        print 'addnum:',readandadd.addnum([2,3])

    if __name__ == '__main__':
        testread()
        testgetnum()
        testaddnum()

运行test.py以后输出结果如下:

    read: 2,3
    getnum: ['2', '3']
    addnum: 5

每一个函数的输出结果一目了然,而且在修改了readandadd.py的函数以后,重新运行test.py就可以知道输出结果有没有符合预期。

当然,这里这个例子非常的简单,因此可以人工通过观察test.py的输出结果来确定是否符合预期,那对于大量的函数的测试,难道也要让肉眼来看吗?当然不是。于是,下一篇文章将会介绍Python的单元测试unittest。

本文分享自微信公众号 - 未闻Code(itskingname),作者:Kingname

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-01-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一日一技:如何更好地理解归并排序?

    在昨天的文章里面,我们已经知道,可以使用 heapq.merge把两个有序列表合并成新的有序列表。

    青南
  • 用图像识别来自动确认网页加载成功

    在对安卓手机设计自动化测试用例的时候,判断一个测试场景是否可以自动化的依据在于其是否需要人的参与。对于wifi能否自动打开关闭,短信能否自动收发这样的场景,不需...

    青南
  • 如何使用闭包进行一次降维打击?

    一个函数内部又定义一个函数,内层函数能够读写外层函数中的变量,外层函数把这个内层函数作为值返回出来。这个内层函数就叫做闭包(Closure)。

    青南
  • UT /SIT/ UAT

    单元测试任务包括:1 模块接口测试;2 模块局部数据结构测试;3 模块边界条件测试;4 模块中所有独立执行通路测试;5 模块的各条错误处理通路测试。;

    公众号php_pachong
  • Spring Boot (2) 构建一个RESTful Web服务

    简单理解 RESTful 就是: “ 用明确的方法 操作 语义清晰的资源,来呈现不同的资源表现形式”。

    zhangyunfeiVir
  • 自查自纠 | 线性回归,你真的掌握了嘛?

    寄语:本文对线性回归算法的原理及模型,学习策略、算法求解和sklearn参数做了详细的讲解。同时,用例子进行Python代码实践。

    Datawhale
  • TextView中DrawableXXX图片无法设置大小的解决方案

    在开发过程中我们往往会遇到图片旁边带文字的布局,这种布局有些比较Low的开发会直接用一个ImageView和TextView,有经验的会给TextView设置D...

    萬物並作吾以觀復
  • 大规模DDoS攻击降低了伊朗25%的互联网连接率

    伊朗再次受到网络攻击,大规模的DDos攻击摧毁了伊朗很大一部分的互联网访问权限。根据专家解释,此次攻击规模巨大,导致伊朗全国互联网连接率下降至75%。

    FB客服
  • 代码中if-else 太多?

    文章转自:https://www.cnblogs.com/davidwang456/p/10831546.html,记录一下

    冯杰宁
  • RNA-seq(2)-1:原始数据下载的几种方法

    第1选择--Aspera Connect 如果aspera connect不能下载,推荐sratoolkit的prefetch功能。尽量不要用wget或curl...

    Y大宽

扫码关注云+社区

领取腾讯云代金券