python pytest_Python项目的pytest初始化

Python项目的pytest初始化

2018-01-19 00:08:25 +08

字数:2310

标签:

Python

Test

为什么要写测试 ¶

Python是一种必须要写测试的语言。

和C/C++、Java这种需要编译的语言相比,Python这种动态语言天生就有开发迅速的优势。

开发完成后的代码,跑一跑自然知道问题。

然而,如果项目稍大,就难以保证手动测试的可靠性。

因此,江湖传言,Python不适合做大型项目。

当然,江湖上的大多数人是不写测试的。

与Java之类相比,没有100%测试覆盖的Python代码,甚至都不能保证没有语法错误。

而静态语言在预编译时,就会做完整的语法检查,可靠性的差距可见一斑。

然而,正是因为这种差距,Python项目有更迫切的测试需求。

达成100%测试覆盖率的Python项目,可靠性却又比没有写测试的Java项目要强上许多。

为什么是pytest ¶

打开PyCharm,可以看到默认支持的单元测试框架有五类:

unittest是Python标准库之一。

与Java里著名的JUnit4非常类似,通过继承一个TestCase,然后增加test_*命名的method来测试。

(JUnit5中已经抛弃了这种做法,改为使用注解@Test的形式。)

它的问题就是,有些过于繁琐。

doctest是一种非常奇特的测试技术,在文档中写测试。

把代码和测试写在一起,这是Java这类语言中没有办法做到的。

虽然它也是Python标准库之一,但孤却第一时间放弃了。

对简单的数学函数,它是很便捷的;但对于复杂的、有副作用(side effect)的function或method来说,它功能不足。

而且,测试代码往往比功能代码更复杂些,不合适写在pydoc里。

Twisted是一个异步网络框架,而Trial则是其单元测试系统,是对unittest的一个封装。

如果不是使用Twisted框架,那么不会使用到它。

nose是一个曾经非常流行的测试,兼容unittest的同时却拥有更加简洁的语法,然而已经停止维护了。

nose本身支持Python 3,然而其很多插件却不支持。

新的项目,不推荐使用它,正如它的文档所说。

非常可惜,孤差点就选它了。

Nose has been in maintenance mode for the past several years and will likely cease without a new person/team to take over maintainership.

New projects should consider using Nose2, py.test, or just plain unittest/unittest2.

最终,孤选择了pytest,曾用名py.test。

它能兼容unittest与nose的测试代码,写法简洁,并且还有自己的独到之处。

在《PythonTestingToolsTaxonomy - Python Wiki》还可看到更多不同类型的测试框架。

本文仅介绍pytest测试最基本的写法,以及如何在一个Python项目进行初始化。

pytest测试样例 ¶

与unittest类似的是,pytest也需要把测试function或method命名为test_*。

方便之处在于,不仅支持function,测试method所在的class也不需要继承什么。

此外,也不需要assert*系列的function来做检验,直接用内置的assert即可。

def add(a, b):

return a + b

def test_add():

assert 3 == add(1, 2)

假如以上代码文件名为add.py,写好后直接运行pytest add.py,即可开始测试。

测试代码结构 ¶

孤认为,测试代码不应该随着Python包而发布,尽管很多知名的包做出了相反的选择。

测试应该在打包发布前完成。

而发布后,用户是不需要、也不应该去跑测试的。

很多自带测试的包,甚至会干扰当前项目的测试结果。

而功能代码与测试代码的分离,通常采用以下形式:

project

├── setup.cfg

├── setup.py

├── src

│   └── mypkg

│   ├── __init__.py

│   └── something.py

└── tests

├── conftest.py

├── test_init.py

└── test_something.py

源码放在src下,而测试则放在tests下。

不把mypkg直接放在根目录下,是为了避免直接从当前路径导入。

这样虽然方便,但有时会导致安装后的代码的未经测试的(通过测试覆盖率的一些异常可以观察到这一情况)。

详情可以查看这篇著名的博文:《Packaging a python library | ionel’s codelog》,它也是pytest官方文档所推荐的。

tests可以增加__init__.py,成为一个Python包,也可以增加子目录、子包。

conftest.py是pytest的默认配置文件,可以在其中放公用的fixture或plugin。

setup.py与setup.cfg ¶

在setup.py的tests_require中,需要配置pytest。

另外,也建议在setup_requires里配置pytest-runner。

from setuptools import setup

setup(

...

setup_requires=[

'pytest-runner',

],

tests_require=[

'pytest',

],

)

即使不配置pytest,也可直接通过运行pytest命令来测试。

而做出以上配置后,可以通过python setup.py pytest命令来测试,并且不用提前安装pytest。

如果需要通过python setup.py test的形式执行测试,则需要添加[aliases]到setup.cfg。

[aliases]

test=pytest

[tool:pytest]

addopts = --verbose

python_files = tests/*

在setup.cfg中的[tool:pytest]块,就是对pytest的配置。

也可在pytest.ini或tox.ini中,添加[pytest]块进行相同配置,效果一样。

不过,配在setup.cfg,可以在项目根目录少一个文件,孤更喜欢一些。

addopts是pytest的命令行参数,--verbose会让打印输出更细致。

python_files指定了测试代码的位置。

有了这两个基本的配置,执行测试时就可以不用输入任何参数了。

后续如果有什么新的参数,也都可以配置到这里。

结语 ¶

一个项目的pytest初始化就是这样。

然后,就可以开始愉快地写测试了。

参考 ¶

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值