说说Python中的单元测试

单元测试是每种编程语言必学的课题,是保护开发者的强力护盾,每一个程序员都在时间容许的状况下尽量多的写单元测试,今天咱们不讨论其必要性,只抛砖引玉聊一聊Python中的单元测试,本文仅表明我的见解。html

标准库中难以忍受的 unittest

不少时候咱们老是认为标准库里的带的老是精挑细选的,若是不通过仔细打磨怎么可能入选为一等公民?但我要告诉你,Python标准库里的单元测试框架真不是最好的,随着你对Python的熟悉你甚至会讨厌这个unittest。python

Python一直崇尚简单,优雅,高效地完成事情,当你写完一个函数须要测试一下时,使用标准库的unittest你须要作这些事情:程序员

  • 新建单元测试脚本
  • 导入单元测试依赖
  • 继承单元测试类
  • 实现单元测试方法

具体的实例代码以下:编程

import unittest

class IntegerArithmeticTestCase(unittest.TestCase):
    def testAdd(self):  # test method names begin with 'test'
        self.assertEqual((1 + 2), 3)
        self.assertEqual(0 + 1, 1)

if __name__ == '__main__':
    unittest.main()

看上去还行,不是很难。可是渐渐地你会吐槽:框架

  • 为啥我要新建一个文件来写测试?
  • 为啥我要继承一个类来写测试?
  • 为啥我要用unittest的Assertion来作断言?
  • 为啥unitunit的命名规则跟最佳实践不同(mixedCase vs lower_case)?

要回答以上问题,答案只有一个:历史缘由编程语言

好久好久之前,Python从Java借鉴了单元测试框架,包括命名规则和实现方式,一直沿用至今。不得不说这个框架没啥毛病,该有的功能的都有,想作的事均可以作,可是用起来老是没有爽的感受。ide

可是为啥伟大的社区力量为啥不把这个框架改的爽一点呢?没办法,我估计是为了世界和平,你要知道Python这个庞然大物能健康地活着,后面有无数的类库和方法在支撑,而这些类库和方法都被单元测试保护着,若是修改了单元测试框架致使兼容性问题,就成了千古罪人。函数

见识简洁的单元测试 pytest

Python中不少大牛其实都有严重的强迫症,追求简洁和优雅的代码。必然的,他们会抛弃标准库中的unittest,使用或者发明本身心仪的单元测试框架。单元测试

正如其名,pytest是一个无数人推荐并在使用的Python单元测试框架,它使用起来很是简单,只要你的方法名以 test 开头就能够,你能够和须要测试的方法放在一块儿,亦或是新建一个文件来专门整理单元测试,均可以。测试

def your_func():
  pass

def test_your_func():
  assert result

这样的设计,就让你写单元测试成了顺手拈来的事,假如你写完了一个方法,想看看是否工做,在旁边直接写上一个test 开头的方法,稍微准备一下数据就能够验证这个方法好很差用,岂不妙哉?

The idioms that pytest first introduced brought a change in the Python community because they made it possible for test suites to be written in a very compact style, or at least far more compact than was ever possible before. Pytest basically introduced the concept that Python tests should be plain Python functions instead of forcing developers to include their tests inside large test classes.

pytest 的发明让你们意识到单元测试原来能够这么轻松和随意,彻底没有必要去继承一个所谓的测试类或者按照复杂的规则才能开始书写测试代码,这也是我选择和推荐它的理由。

固然,若是原来你的单元测试时unittest写的话,pytest其实也是有可能兼容的的。

pytest 可以识别 unittest.TestCase 子类中的测试方法,若是文件名符合 test_*.py 或者 *_test.py 这样的规则。

而且大多数 unittest 的功能都是被支持的,例如:

  • @unittest.skip 装饰器;
  • setUp/tearDown;
  • setUpClass/tearDownClass();

我以为,pytest有如下优势:

  • 上手和使用足够简单
  • 当case失败时信息足够丰富和直观,好比最后致使失败的变量值会打印出来
  • 更丰富的运行参数
  • 可使用 assert 而不是 self.assert*
  • 被广大IDE支持,社区资源丰富,用户群体大

让单元测试和IDE无缝集成

毕竟咱们大多数人都不是神,不能用记事本写代码,IDE才是咱们正确搬砖的方式。Python的首选IDE毋庸置疑就是 JetBrain 公司出品的 PyCharm

在PyCharm中只要你将默认的单元测试驱动改为pytest,就能够在任意test开头的方法上经过右键菜单运行或者调试这个测试案例,很是方便。

更改PyCharm设置

右键菜单运行或者调试

若是你要运行当前文件的全部测试,只要从非test方法的其余区域点击右键便可。或者修改任意已经运行过的Configuration,添加你想要的参数,好比最多运行挂3个case就终止测试等等。

自定义Run Configuration

闲话和总结

单元测试的重要性你们都知道,大名鼎鼎的TDD应该都听过,可是真正在实践的少之又少。

究其缘由,一些人会说时间写代码都不够,哪还有空写单元测试。还有一些人就是嫌麻烦,在绝大多数编程语言里单元测试都是须要单独创建工程和目录的,写单元测试须要不少基础工做要作,本觉得顺手就能够写的单元测试,实际上须要费九牛二虎之力仍是在搭架子,太沮丧了。

Python的动态特性和灵活性让它有可能让单元测试超级简单,有可能你认为单元测试仍是不要和业务代码混合在一块儿的好,那就多辛苦一点新建一个文件导入要测试的方法,写一个 test 开头的方法便可,不算太难,不要找辞让的理由。

最后个人我的观点,单元测试其实还有一个很是重要的做用,就是替代函数文档注释。好比你写了一个函数,使用起来可能有那么一点复杂,你能够给它写一份清晰的注释文档,可是千言万语不如给我来个例子,单元测试能够充当例子的角色,什么样的输入,输出结果如何,一目了然。

但愿从今天起,你的代码也都有单元测试。

关于做者:

Toby Qin, Python 技术爱好者,目前从事测试开发相关工做,转载请注明原文出处。

欢迎关注个人博客 https://betacat.online,你能够到个人公众号中去当吃瓜群众。

Betacat.online

相关文章
相关标签/搜索