一、常用参数详解
--help,查看帮助
--collect-only 展示将要执行的测试用例,而不执行。
-k 通过指定测试用例名称表达是来执行测试用例。
-m 用于执行被标记的测试用例。
-m ‘not 标签’
pytest -m p0
仅运行用@pytest.mark.p0 装饰器修饰的所有测试用例
如果要运行多个标识,可使用表达式
pytest -m “p1 or p2” #运行有p1标识或p2标识用例
pytest -m “p1 and p2” #运行有p1和p2标识的用例
pytest -m “not p1” #运行除了p1之外的标识的用例
pytest -m “p1 and not p2” #运行有p1和没有p2标识的用例-x 出现失败测试用例就停止执行。
--maxfail=num 允许执行失败的次数。
-s 允许在测试时输出信息。
--lf 重新执行上一个测试失败的用例
--ff 重新执行全部用例,优先执行上一次失败的用例。
-v 输出更详细的信息
-q 简化输出信息
-l 失败的测试用例被堆栈追踪
--tb=style 用于决定不到到失败时暑促信息的显示方式(short,line,no)
--duration=N 统计测试阶段的执行时间
二、使用方法:
1、测试文件的命名格式:test_<something>.py 或者 <something>_test.py。
2、测试函数、测试类的方法命名:test_<something>。
3、测试类命名Test<Something>。
4、标记测试函数,使用@pytest.mark,例如: @pytest.mark.smoke,执行时是哦那个pytest -m marker_name,运行。可以接 and、or、not关键字。例如:pytest -m 'smoke and get' test.py
5、跳过测试。skip、skipif。如过在测试时希望看到跳过测试的原因可以使用 pytest -rs。
6、标记预期会失败的用力使用:@pytest.mark.xfail(task.__version__<'0.2.0', reason='not supported until version 0.2.0')
7、传递参数:@pytest.mark.parametrize(key_list_string,value_list)。例如:@pytest.mark.parametrize('task1,task2',[[1,2]]),支持id标识。例如:
task_to_try = ( Task('sleep', done=True),
Task('wake', 'brian'),
Task('breathe','BRIAN',True))
task_ids = [ 'Task({},{},{})'.format(t.summary, t.owner, t.done) for t in task_to_try]
@pytest.mark.parametrize('task', task_to_try, ids=task_ids)
def test_add(task):
task_id = tasks.add(task)
assert equivalent(...)还可以在参数旁定义一个id来做标识,语法是 pytest.param(<value>, id="something"),例如
@pytest.mark.parametrize('task',[pytest.param(Task('create', 'Michelle'), id='just summary')])
三、Fixture
@pytest.fixture()用于声明函数是一个fixture。fix可以完成任务,也可以返回数据给测试函数。
例如:
@pytest.fixture()
def some_data():
...
def test_some_data(some_data):fixture函数的搜索顺序是,先搜索当前模块,然后搜索conftest.py。conftest.py可以被pytest视作一个fixture仓库。
如果fixture函数包含yield,那么系统会在yield处停止后面的代码,执行测试函数,因此,可以将yield之前的代码是为配置setup过程,yield后面的代码是为teardown过程。无论测试发生里什么yield之后的代码都会被执行。
下面这种用法也可以:
@pytest.fixture()
def a_tuple():
return (1, 'foo', None, {'bar':23})
def test_a_tuple(a_tuple):
asssert a_tuple[3]['bar'] == 32我们可以在测试中使用多个fixture函数。
@pytest.fixture()
def db_with_task1():
...
@pytest.fixture()
def db_with_task2(db_with_task1):
...
@pytest.fixture()
def db_with_task3(db_with_task1, db_with_task2):
...
def test_add_count(db_with_task3):
fixture的作用范围:通过scope来指定,参数有:function(函数级别),class(测试类级别),module(模块级别),session(会话级别)。
@pytest.fixtuer(scope='function')
使用usefixtures可以指定fixture。
为常用fixture添加autouse选项。通过指定autouse=True选项使作用域内的测试函数都运行改fixture。
fixture传参,通过params参数,在函数中通过request.param调用。例如
@pytest.fixture(params=['tiny', 'mongo'])
def task_db_session(tmpdir, request):
task.start_task_db(str(temp_dir), request.param)
yield
task.stop_task_db()常用的内置Fixture
tmpdir和tmpdir_factory
a_file = tmpdir.join('something.txt')
a_sub_dir = tmpdir.mkdir('anything')
another_file = a_dir.join('something_else.txt')
a_dir = tmpdir_factory.mktemp('mydir')
base_dir = tmpdir_factory.getbasetemp()
a_file = a_dir.join('something.txt')
a_sub_dir = a_dir.mkdir('anything')
another_file = a_sub_dir.join(something_else.txt)pytestconfig:为测试添加配置选项可以通过pytest_addoption或者在顶层目录的conftest.py中完成。
通过pytest_addoption()添加选项:
# /pytestconfig/conftest.py
def pytest_addoption(parser):
parser.addoption("--myopt", action="store_true", help="some boolean option")
parser.addoption("--foo", action="sotre", default="bar", help="foo: bar or baz")注意:pytestconfig 是一个内建fixture,可以被其他测试函数或者fixture使用。
def test_pytestconfig(pytestconfig):
print('args :', pytestconfig.args)
print('inifile :', pytestconfig.inifile)
print('invocation_dir :', pytestconfig.invocation_dir)
print('rootdir :', pytestconfig.rootdir)
print('-k EXPRESSION :', pytestconfig.getoption('keyword'))
print('-v, --verbose :', pytestconfig.getoption('verbose'))
print('-q, --quiet :', pytestconfig.getoption('quiet'))
print('-l, --showlocals :', pytestconfig.getoption('tbstyle'))capsys:内置的capsys有两个功能:1、允许使用代码读取stdout和stderr;2、可以临时禁止抓取日志输出。例如:
# /ch4/cap/test_capsys.py
def greeting(name):
print('Hi, {}'.format(name))
def test_greeting(capsys):
greeting('Earthling')
out,err = capsys.readouterr()
assert out == 'Hi, earthling\n'
assert err == ''pytest通常会抓取测试用例及被测试代码的输出。仅当全部测试会话运行结束后,抓取到的输出才会随着失败用例显示出来。
-s 参数可以关闭这个功能,在测试仍在运行期间就把输出直接发送到stdout。
你可以使用capsys.disabled() 让输入绕过默认的输出捕获机制。
monkeypatch可以在运行期间对类或者模块进行动态修改。monkeypatch提供以下函数:
setattr(target, name, value=<notset>, raising=True):设置一个属性。
delattr(target, name=<notset>, raising=True):删除一个属性。
setitem(dic, name, value):设置字典中的一条记录。
delitem(dic, name, raising=True):删除字典中的一条记录。
setenv(name, value, preend=None):设置一个环境变量。
delenv(name, raising=True):删除一个环境变量
syspath_prepend(path):将路径path加入sys.path并放在最前面。sys.path是Python导入的系统路径类表。
chdir(path):改变当前工作目录。
raising参数用于指示pytest是否在记录不存在时抛出异常。setenv()函数里的prepend可以是一个字符,如果这样设置的话,那么环境变量的值就是value+prepend+<old value>
# ch4/monkey/cheese.py
_default_prefs={
"slicing": ['manchego', 'sharp cheddar']
"spreadable": ['Saint Andre', 'camebert']
"salads": ['crumbled feta']
}
# ch4/monkey/test_cheese.py
def test_def_change_default(tmpdir,monkeypatch):
fake_home_dir = tmpdir.mkdir('home')
monkeypatch.setattr(cheese.os.path, 'expanduser', (lambda x:x.replace('~', str(fake_home_dir))))
monkeypatch.setitem(cheese._default_prefs, 'slicing', ['provolone'])doctest模块是Python标准库的一部分。你可以使用--doctest-modules标识搜寻doctest测试用例。
doctest_namespace能够使doctest中的测试用例在运行时识别某些用于pytest命名空间的字符标识。
"""
this moudles defines multiply(a, b) and divide(a, b).
>>> import unnecessary_math as um
Here's how you use multiply:
>>>um.multiply(4, 3)
12
>>>um.multiply('a', 3)
'aaa'
Here's how you use divide:
>>>um.divide(10, 5)
2.0
"""
def multiply(a, b):
"""
Returns a multiplied by b.
>>>um.multiply(4, 3)
12
"""正常情况下pytest会把每个字符串里的代码看成是不同的测试用例。
recwarn用来检测代码产生的警告信息。
#/ch4/test_warning.py
import warnings
import pytest
def lame_function():
warnings.warn("Please stop using this", DeprecationWarning)
def test_lame_function():
lame_function()
assert len(recwarn) == 1
w = recwarn.pop()
assert w.category == DeprecationWarning
assert str(w.message) == 'Please stop using this'四、配置文件
pytest.ini:pytest.ini的主配置文件,可以改变pytest的默认配置。
conftest.py:是本地插件库,其中hook函数和fixture将作用于该文件所在的目录以及所有的子目录。
__init__.py:每个测试子目录都包含该文件时,那么在多个测试目录中可以出现同名测试文件。
tox.ini:如果你使用tox工具会用到的配置文件。
#/ch6/pytest.ini
[pytest]
addopts = -rsxX -l --tb=short --strict
xfail_strict = true
...more options...
tox.ini
#/ch6/tox.ini
[pytest]
addopts = -rsxX -l --tb=short --strict
xfail_strict = true
...more options...
setup.cfg
#/ch6/setup.cfg
[tool:pytest]
addopts = -rsxX -l --tb=short --strict
xfail_strict = true
...more options...
pytest.ini文件的所有设置选项。
[pytest] ini-options in the first pytest.ini|tox.ini|setup.cfg file found:
markers (linelist): markers for test functions
empty_parameter_set_mark (string):
default marker for empty parametersets
norecursedirs (args): directory patterns to avoid for recursion
testpaths (args): directories to search for tests when no files or
directories are given in the command line.
usefixtures (args): list of default fixtures to be used with this project
python_files (args): glob-style file patterns for Python test module
discovery
python_classes (args):
prefixes or glob names for Python test class discovery
python_functions (args):
prefixes or glob names for Python test function and
method discovery
disable_test_id_escaping_and_forfeit_all_rights_to_community_support (bool):
disable string escape non-ascii characters, might cause
unwanted side effects(use at your own risk)
console_output_style (string):
console output: "classic", or with additional progress
information ("progress" (percentage) | "count").
xfail_strict (bool): default for the strict parameter of xfail markers when
not given explicitly (default: False)
junit_suite_name (string):
Test suite name for JUnit report
junit_logging (string):
Write captured log messages to JUnit report: one of
no|system-out|system-err
junit_log_passing_tests (bool):
Capture log information for passing tests to JUnit
report:
junit_duration_report (string):
Duration time to report: one of total|call
junit_family (string):
Emit XML for schema: one of legacy|xunit1|xunit2
doctest_optionflags (args):
option flags for doctests
doctest_encoding (string):
encoding used for doctest files
cache_dir (string): cache directory path.
filterwarnings (linelist):
Each line specifies a pattern for
warnings.filterwarnings. Processed after -W and
--pythonwarnings.
log_print (bool): default value for --no-print-logs
log_level (string): default value for --log-level
log_format (string): default value for --log-format
log_date_format (string):
default value for --log-date-format
log_cli (bool): enable log display during test run (also known as "live
logging").
log_cli_level (string):
default value for --log-cli-level
log_cli_format (string):
default value for --log-cli-format
log_cli_date_format (string):
default value for --log-cli-date-format
log_file (string): default value for --log-file
log_file_level (string):
default value for --log-file-level
log_file_format (string):
default value for --log-file-format
log_file_date_format (string):
default value for --log-file-date-format
addopts (args): extra command line options
minversion (string): minimally required pytest version1、addopts用来配置常用设置。
[pytest]
addopts = -rsxX -l --tb -strict--rsxX 表示pytest报告所有测试用例被跳过、预计失败、预计失败但实际通过的原因。
-l表示pytest报告所有失败测试的堆栈中的局部变量。
--tb=short表示简化堆栈回溯信息,指保留文件和行数。
--strict选项表示禁止使用未在配置文件中注册的标记。
2、注册标记来防范拼写错误 --strict
[pytest]
markers =
smoke: Run the smoke test functions for tasks project
get : Run the test functions that test tasks.get()通过pytest --markers来查看注册过的标记。
3、指定pytest的最低版本号。
minversion选项可以指定运行测试用例的pytest的最低版本。
[pytest]
minversion = 3.04、指定pytest忽略某些目录。使用norecurse简化pytest的搜索工作。
默认设置是.* build dist CVS _darcs {arch} 和 *.egg。因为有.*,所以将虚拟环境命名为.venv是一个好主意例如
[pytest]
norecursedirs = .* venv src *.egg dist build5、指定测试目录testpaths。
testpaths是一系列相对于根目录的路径,用于指定测试用例的搜索范围。
[pytest]
testpaths = tests6、更改测试搜索规则。
pyhon_classes python_files python_functions
[pytest]
python_classes = *Test Test* *Suite
python_files = test_* *_test check_*
python_function = test_* check_*7、在所有的测试子目录下都有一个__init__.py文件,目的是可以在多个目录中使用同名的文件。
五、常用的工具
1、pdb
调试常用项
--tb=[auto/long/short/line/native/no]:指定堆栈回溯信息粒度。
-v/--verbose:显示所有测试用例的名字,测试通过情况。
-l/showlocals:显示错误堆栈中的局部变量。
-lf/--last-failed:只运行上次失败的测试。
-x/--exitfirst:当测试遇到错误时即停止。
--pdb:在错误出现时开启交互调试。
pdb查看错误时的常用命令:
p/print expr:输出expr值。
pp expr:美化输出expr值。
l/list:列出错误并显示错误之前和之后的5行代码。
l/list begin,end:列出错误,并通过行号指定需要显示的代码区域。
a/args:打印当前函数的参数列表。
u/up:移动到堆栈的上一层。
d/down:移动到堆栈的下一层。
q/quit:退出当前调试会话。
例如:
(Pdb) p new_task
(Pdb) p task_id
(Pdb) q2、coverage.py判断测试覆盖了多少代码
pytest-cov插件,会自动引入coverage.py。
3、mock替换部分系统
4、tox测试多种配置
5、Jenkins集成测试
六、测试的目录结构

七、测试结果含义
XPASSED(.):测试通过
FAILED(F):测试失败
SKIPPED(s):测试未被执行。
xfail(x):预期测试失败,并且确实失败。
XPASS(X):预期失败,但实际通过运行。
ERROR(E):测试用例之外的代码触发了异常。