帮助你更好的书写程序
成熟全功能的Python测试工具 支持POSIX /
Windows, Python的2.5-3.3 , PyPy和Jython - 2.5.1
1000测试用例自测零bug。
pytest升级时有很好的向后兼容性
丰富的在线和PDF文档
大量的第三方插件和内置帮助
在许多小型和大型项目和组织使用
许多测试实例
灵活 易学,有多种用法
assert语句断言
追踪和失败断言报告
打印调试和测试执行期间可以捕获标准输出
适合简单的单元测试到复杂的功能测试 模块化和参数化的平台
参数化的测试函数
支持属性
Skip和xfail处理失败的用例
xdist插件分发测试给多个CPU
不断地重新运行失败的测试
灵活的Python测试发现
集成 多范式:可以执行nose, unittest 和doctest风格的测试用例,甚至Django和trial。
支持良好的集成实践
支持扩展的xUnit风格setup
支持非python测试
支持生成测试覆盖率报告
支持PEP8兼容的编码风格
扩展插件和定制系统: 所有的收集,报告,运行方面都委派给hook函数
定制可以是每个目录,每个项目或每个PyPI上发布的插件
很容易添加命令行选项或定制现有的行为
安装和入门
安装
pip install -U pytest # oreasy_install -U pytest
检查版本:
# py.test --versionThis is pytest version 2.5.2, imported from /usr/lib/python2.7/site-packages/pytest.pyc
第一个实例:
代码:
# content of test_sample.py
deffunc(x):
return x + 1
deftest_answer():
assert func(3) == 5
执行结果:
# py.test
=========================================================================================================== test session starts ===========================================================================================================
platform linux2 -- Python 2.7.3 -- py-1.4.20 -- pytest-2.5.2
collected 1 items
test_sample.py F
================================================================================================================ FAILURES =================================================================================================================
_______________________________________________________________________________________________________________ test_answer _______________________________________________________________________________________________________________
deftest_answer():
> assert func(3) == 5
E assert 4 == 5
E + where 4 = func(3)
test_sample.py:8: AssertionError
======================================================================================================== 1 failed in 0.34 seconds =========================================================================================================
pytest通过标准测试发现规则发现test_answer函数,通常是查找
test_前缀。我们得到了一个故障报告,因为我们调用func(3)没有返回5。pytest的高级內省断言会智能报告assert的中间值,不需要记住那些JUnit传统方法。
异常断言
代码:
import pytest
deff():
raise SystemExit(1)
deftest_mytest():
with pytest.raises(SystemExit):
f()
执行结果:
$py.test -q test_sysexit.py
.
1 passed in 0.01 seconds
-q表示静默模式:
-q, --quiet decrease verbosity.
在类中分组用例
代码
# content of test_class.py
classTestClass:
deftest_one(self):
x = "this"
assert 'h' in x
deftest_two(self):
x = "hello"
assert hasattr(x, 'check')
执行结果:
# py.test test_class.py
=========================================================================================================== test session starts ===========================================================================================================
platform linux2 -- Python 2.7.3 -- py-1.4.20 -- pytest-2.5.2
collected 2 items
test_class.py .F
================================================================================================================ FAILURES =================================================================================================================
___________________________________________________________________________________________________________ TestClass.test_two ____________________________________________________________________________________________________________
self =
deftest_two(self):
x = "hello"
> assert hasattr(x, 'check')
E assert hasattr('hello', 'check')
test_class.py:12: AssertionError
=================================================================================================== 1 failed, 1 passed in 0.01 seconds ====================================================================================================
功能测试示例:生成唯一的临时目录
功能测试经常需要创建一些文件,并将其传递给应用程序对象。pytest提供 Builtin fixtures/function
参数允许请求任意资源,例如唯一的临时目录:
deftest_needsfiles(tmpdir):
print tmpdir
assert 0
执行结果:
]# py.test -q test_tmpdir.py
FF
================================================================================================================ FAILURES =================================================================================================================
_____________________________________________________________________________________________________________ test_needsfiles _____________________________________________________________________________________________________________
tmpdir = local('/tmp/pytest-0/test_needsfiles0')
deftest_needsfiles(tmpdir):
print tmpdir
> assert 0
E assert 0
test_tmpdir.py:7: AssertionError
------------------------------------------------------------------------------------------------------------- Captured stdout -------------------------------------------------------------------------------------------------------------
/tmp/pytest-0/test_needsfiles0
1 failed in 0.07 seconds
断言的前面的print内容也会打印出来,测试时可以多加print语句,保证异常时输出一些有用的信息。
下面方式可以查看内置的
# py.test --fixtures
=========================================================================================================== test session starts ===========================================================================================================
platform linux2 -- Python 2.7.3 -- py-1.4.20 -- pytest-2.5.2
collected 5 items
capsys
enables capturing of writes to sys.stdout/sys.stderr and makes
captured output available via ``capsys.readouterr()`` method calls
which return a ``(out, err)`` tuple.
capfd
enables capturing of writes to file descriptors 1 and 2 and makes
captured output available via ``capsys.readouterr()`` method calls
which return a ``(out, err)`` tuple.
monkeypatch
The returned ``monkeypatch`` funcarg provides these
helper methods to modify objects, dictionaries or os.environ::
monkeypatch.setattr(obj, name, value, raising=True)
monkeypatch.delattr(obj, name, raising=True)
monkeypatch.setitem(mapping, name, value)
monkeypatch.delitem(obj, name, raising=True)
monkeypatch.setenv(name, value, prepend=False)
monkeypatch.delenv(name, value, raising=True)
monkeypatch.syspath_prepend(path)
monkeypatch.chdir(path)
All modifications will be undone after the requesting
test function has finished. The ``raising``
parameter determines if a KeyError or AttributeError
will be raised if the set/deletion operation has no target.
pytestconfig
the pytest config object with access to command line opts.
recwarn
Return a WarningsRecorder instance that provides these methods:
* ``pop(category=None)``: return last warning matching the category.
* ``clear()``: clear list of warnings
See http://docs.python.org/library/warnings.html for information
on warning categories.
tmpdir
return a temporary directory path object
which is unique to each test function invocation,
created as a sub directory of the base temporary
directory. The returned object is a `py.path.local`_
path object.
============================================================================================================ in 0.02 seconds =============================================================================================================
使用和调用
python -m
pytest调用: python -m
pytest [...] 效果和py.test [...] 一样
获取版本,选项名,环境变量 py.test
--version 看版本
py.test
--fixtures 查看内置参数
py.test -h |
--help 命令行和配置文件帮助
失败后停止 首次失败后停止执行:py.test -x
py.test
--maxfail=2 两次失败之后停止执行
执行选择用例 py.test
test_mod.py,执行模块中的用例
py.test
somepath,执行路径中用例
py.test -k
stringexpr,执行字符串表达式中的用例,比如"and not
method",选择TestMyClass.test_something,排除了TestMyClass.test_method_simple。
py.test
--pyargs pkg,导入pkg,使用其文件系统位置来查找和执行用例。执行pypkg目录下的所有用例。
调试输出: py.test
--showlocals 在traceback中显示本地变量
py.test -l
在traceback中显示本地变量(快捷方式)
py.test
--tb=long 默认的traceback信息格式化形式
py.test
--tb=native 标准库格式化形式
py.test
--tb=short 更短的格式
py.test
--tb=line 每个错误一行
失败时调用PDB
(Python Debugger):
Python带有一个内置的Python调试器称为PDB。pytest可以在命令行选项指定调用:
py.test --pdb
这将每次失败时调用Python调试器。
py.test -x --pdb # 失败时调用pdb,然后退出测试。
py.test --pdb - maxfail=3# 前3次失败调用pdb。
设置断点:
import pytest
deftest_function():
...
pytest.set_trace() # invoke PDB debugger and tracing
以前的版本中只有通过py.test-s禁用命令行捕捉才可以进入pdb调试。
Profiling测试执行时间:得到最执行慢的10个测试:
py.test --durations=10
创建JUnitXML格式的文件
创建Hudson或其他持续集成服务器的结果文件:
py.test --junitxml=path
创建resultlog格式的文件
要创建纯文本的机器可读的结果文件,用于PyPy-testweb展示等。
py.test --resultlog=path
发送测试报告给在线pastebin服务
bpaste可以为你的文本生成url连接,下面为创建每个测试失败创建一个url:
py.test --pastebin=failed
py.test --pastebin=all
py.test --pastebin=failed -x
目前只支持:py.test --pastebin=failed
禁用插件
py.test -p no:doctest
在python代码中调用pytest
pytest.main([’-x’, ’mytestdir’])
pytest.main("-x mytestdir")
# 指定插件
# content of myinvoke.py
import pytest
classMyPlugin:
defpytest_sessionfinish(self):
print("***test run reporting finishing")
pytest.main("-qq", plugins=[MyPlugin()])
执行结果:
$python myinvoke.py
***
test run reporting finishing
好的集成实践
使用虚拟环境
#virtualenv .New python executable in ./bin/python
Installing setuptools, pip...done.
root@AutoTest:[/data/code/python/pytest]#source bin/activate(pytest)root@AutoTest:[/data/code/python/pytest]#pip install pytestDownloading/unpacking pytest
Downloading pytest-2.5.2.tar.gz (608kB): 608kB downloaded
Running setup.py (path:/data/code/python/pytest/build/pytest/setup.py) egg_info forpackage pytest
Downloading/unpacking py>=1.4.20 (from pytest)
Downloading py-1.4.22.tar.gz (189kB): 189kB downloaded
Running setup.py (path:/data/code/python/pytest/build/py/setup.py) egg_info forpackage py
Installing collected packages: pytest, py
Running setup.py install forpytest
Installing py.test-2.7 script to /data/code/python/pytest/bin
Installing py.test script to /data/code/python/pytest/bin
Running setup.py install forpy
Successfully installed pytest py
Cleaning up...
测试布局和导入规则
测试布局的方法有2种。一为放置在应用代码之外,适用于有很多功能测试等情况。
setup.py # your distutils/setuptools Python package metadata
mypkg/
__init__.py
appmodule.py
tests/
test_app.py
...
二为嵌入测试目录到应用,当(单元)测试和应用之间的有直接关系,并想一起发布时有用:
setup.py # your distutils/setuptools Python package metadata
mypkg/
__init__.py
appmodule.py
...
test/
test_app.py
...