Python和单元测试

栏目: Python · 发布时间: 5年前

内容简介:以前我是不写任何测试的,后来偶尔写单元测试,现在我主动写单元测试 ----- 不得 不承认,测试是有其存在必要性的,要说为什么的话,大概又会引发语言的强弱类型和 是否静态语言之争了吧。就目前而言,个人认为写单元测试的好处有以下几点:缺点嘛:耗费时间。单元测试和文档一样,属于非常重要,但是非常耗费时间的工作, 因为要考虑齐全,考虑到的边界条件越多,测试覆盖率越高,程序越可靠,而想这些东 西是很耗费时间精力的。

以前我是不写任何测试的,后来偶尔写单元测试,现在我主动写单元测试 ----- 不得 不承认,测试是有其存在必要性的,要说为什么的话,大概又会引发语言的强弱类型和 是否静态语言之争了吧。

就目前而言,个人认为写单元测试的好处有以下几点:

  • 当修改了代码之后,单元测试可以保证API不会发生变化(假设原需求就不需API发生 变化)。这点可能一般情况下没什么感觉,但是当你去修改前辈留下的代码的时候, 你就会感谢他写了单元测试,最少让你知道了从功能上,这个函数是干什么的,而且 能保证你修改了函数内部实现,但是不影响函数功能。

  • 写单元测试的时候会回想函数的作用,从而自动对函数进行回想和 review

缺点嘛:耗费时间。单元测试和文档一样,属于非常重要,但是非常耗费时间的工作, 因为要考虑齐全,考虑到的边界条件越多,测试覆盖率越高,程序越可靠,而想这些东 西是很耗费时间精力的。

吐槽完毕,我们来说说目前我知道的几个和测试有关的东西(全程 Python 3 )。

Mock

Mock是个好东西呀,遇到测试中出现的不可预知的或者不稳定因素,就用 Mock 来代 替。例如查询数据库(当然像目前我们用的MongoDB,由于特别灵活,可以直接在代码里 把相应的collection替换掉),例如异步任务等。举个例子:

import logging
from unittest.mock import Mock

logging.basicConfig(level=logging.DEBUG)


#  code
class ASpecificException(Exception):
    pass


def foo():
    pass


def bar():
    try:
        logging.info("enter function <foo> now")
        foo()
    except ASpecificException:
        logging.exception("we caught a specific exception")


#  unittest
def test_foo():
    foo = Mock(side_effect=ASpecificException())  # noqa

    logging.info("enter function <bar> now")
    bar()
    logging.info("everything just be fine")


if __name__ == "__main__":
    test_foo()

运行一下:

root@arch tests: python test_demo.py
INFO:root:enter function <bar> now
INFO:root:enter function <foo> now
INFO:root:everything just be fine

duang,一个简单的测试就这么写好了。来,跟我念, Mock 大法好呀!

doctest

doctest属于比较简单的测试,写在 docstring 里,这样既能测试用,又能当文档 示例,是在是好用之极啊。缺点是,如果测试太复杂,doctest就显得太臃肿了(例如 如果测试之前要导入一堆东西)。举个例子:

import logging

logging.basicConfig(level=logging.DEBUG)


def foo():
    """A utility function that returns True

    >>> foo()
    True
    """
    return True


if __name__ == "__main__":
    import doctest
    logging.debug("start of test...")
    doctest.testmod()
    logging.debug("end of test...")

测试结果:

[email protected] tests: python test_demo.py
DEBUG:root:start of test...
DEBUG:root:end of test...

unittest

这个文档确实有点长,我感觉还是仔细去读一下文档比较好(虽然我也没读完)。

import unittest


class TestStringMethods(unittest.TestCase):
    def setUp(self):
        self.alist = []

    def tearDown(self):
        print(self.alist)

    def test_list(self):
        for i in range(5):
            self.alist.append(i)


if __name__ == '__main__':
    unittest.main()
[email protected] tests: python test_demo.py
[0, 1, 2, 3, 4]
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

unittest框架配合上Mock,单元测试基本无忧啦。

pytest

上面的单元测试跑起来比较麻烦,当然也可以写一个脚本遍历所有的单元测试文件,然 后执行。不过 pytest 对unittest有比较好的支持。

pytest默认支持的是 函数 风格的测试,但是我们可以不用这一块嘛(而且很多时候 还是很有用的)。走进项目根目录,输入 pytest 就可以啦。它会自动发现 test_ 开头的文件,然后执行其中 test_ 开头的函数和 unittesttest_ 开头的 方法。

[email protected] tests: pytest
========================================================= test session starts =========================================================
platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0
rootdir: /root/tests, inifile:
collected 1 items

test_afunc.py .

====================================================== 1 passed in 0.03 seconds =======================================================
[email protected] tests:

总结

编译器没给 python 做检查,就只有靠我们手写测试了 :(

另外其实 pytestunittest 都有很多强大的特性,例如 fixture (不知道 咋翻译好),例如 skip 掉某一部分测试。当然我也是知之甚少,所以还是看文档吧。


以上所述就是小编给大家介绍的《Python和单元测试》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

增长黑客实战

增长黑客实战

范冰、张溪梦 / 电子工业出版社 / 2017-6 / 59.00

《增长黑客实战》围绕硅谷前沿的增长黑客职业,讲解增长理念的树立、增长团队的组建、流程制度的创立、技术营销的运用等团队运营成功实战经验。作者以自身创业经验为蓝本,结合真实案例,并融入一些伟大创业者的智慧,创建了一套思考、验证和追求卓越增长的理论体系。那些想要验证自己的创意、解决实际增长问题和拥有成功事业的人,可以将《增长黑客实战》当成一套清晰的实践指南、一幅组建增长团队的指导蓝图,或者一套值得反复玩......一起来看看 《增长黑客实战》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具