https://blog.csdn.net/venustech0919/article/details/135495254
https://blog.csdn.net/venustech0919/article/details/135521739
https://blog.csdn.net/venustech0919/article/details/135522722
https://blog.csdn.net/venustech0919/article/details/135546262
接上文 :
在pytest中,常用到的两个配置文件 ,分别是pytest.ini和conftest.py .
pytest.ini主要包含
- pytest.ini是什么?
- pytest.ini编写格式
- pytest.ini包含的选项 。
- pytest的常用选项
conftest.py主要包含:
- conftest.py是什么 ?
- conftest.py有什么作用
- conftest.py 使用规则
- 需求 :在conftest中实现登录fixture.
1.pytest.ini是什么 ?
pytest.ini文件是pytest的主配置文件;pytest.ini文件的位置一般放在项目的根目录下,不能随便放,也不能更改名字。在pytest.ini文件中都是存放的一些配置选项 ,这些选项都可以通过pytest -h
查看到 。
2.pytest.ini的编写格式
你可能已经看到 ,它的后缀是ini ,这也是标准配置文件的一种 ,而pytest也仅仅是引用了这种配置文件 ,所以 ,既然使用了这种文件,你就得知道它的规则 。
INI文件由节、键、值组成。
节
[section]
选项/参数(键=值)
name=value
注释
注释使用分号表示(;)。在分号后面的文字,直到该行结尾都全部为注释。
以下就是一个ini的示例 。
[pytest]
addopts = -s -v --reruns 1 --alluredir=./result --clean-alluredir
testpaths = ./testcase/webui/test_register
;python_files = *.py
;python_classes = *
;python_functions = rui*
markers =
smoke
regression
slow
serial
3.pytest.ini包含的选项**
我们知道了ini文件的编写规则 ,但是你知道pytest.ini里的选项是怎么定义的呢 ?是随意写还是有要求呢 ?其实在pytest.ini里能添加哪些,都是事先已经定义好了 ,你可以打开cmd窗口执行pytest -h查看 。以下这些都是在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.
filterwarnings (linelist):
Each line specifies a pattern for warnings.filterwarnings. Processed after -W/--pythonwarnings.
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)
enable_assertion_pass_hook (bool):
Enables the pytest_assertion_pass hook.Make sure to delete any previously generated pyc cache
files.
junit_suite_name (string):
Test suite name for JUnit report
junit_logging (string):
Write captured log messages to JUnit report: one of no|log|system-out|system-err|out-err|all
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.
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
log_auto_indent (string):
default value for --log-auto-indent
pythonpath (paths): Add paths to sys.path
faulthandler_timeout (string):
Dump the traceback of all threads if a test takes more than TIMEOUT seconds to finish.
addopts (args): extra command line options
minversion (string): minimally required pytest version
required_plugins (args):
plugins that must be present for pytest to run
rsyncdirs (pathlist): list of (relative) paths to be rsynced for remote distributed testing.
rsyncignore (pathlist):
list of (relative) glob-style paths to be ignored for rsyncing.
looponfailroots (pathlist):
directories to check for changes
environment variables:
PYTEST_ADDOPTS extra command line options
PYTEST_PLUGINS comma-separated plugins to load during startup
PYTEST_DISABLE_PLUGIN_AUTOLOAD set to disable plugin auto-loading
PYTEST_DEBUG set to enable debug tracing of pytest's internals
所以,你应该从这里开始往下看 。
虽然,我们看到它支持很多参数的配置 ,但其实真正用到的不多 。
参数1:markers
[pytest]
markers=
p1
p2
p3
p4
比如如下代码 :
"""
pytest所支持的setup和tearDown .
"""
import pytest
from package_pytest.login import login
# case1 : 输入正确的用户名和正确的密码进行登录
@pytest.mark.p1
def test_login_success():
print("1")
expect_result = 0
actual_result = login('admin','123456').get('code')
assert expect_result == actual_result
# case2 : 输入正确的用户名和错误的密码进行登录
@pytest.mark.p2
def test_password_is_wrong():
print("2")
expect_reesult = 3
actual_result = login('admin','1234567').get('code')
assert expect_reesult == actual_result
# case3 : 输入用户名和空的密码进行登录
@pytest.mark.abc
def test_password_is_null():
print("3")
expect_reesult = 2
actual_result = login('admin', '').get('code')
assert expect_reesult == actual_result
if __name__ == '__main__':
pytest.main(['test08_login_mark.py','-sv','-m','p1'])
请注意 ,以上的第3条测试用例中标记的是abc ,而这个值在pytest.ini中的markers没有 ,故运行后给出警告 ,具体如下 :
但如果把这个abc换成markers里的值,就不会给出警告。
参数2:disable_test_id_escaping_and_forfeit_all_rights_to_community_support
[pytest]
disable_test_id_escaping_and_forfeit_all_rights_to_community_support = True
具体代码如下 :
import pytest
from package_pytest.login import login
cases = [(0,'admin','123456'),(3,'admin','1234567'),(2,'admin',''),(1,'','123456')]
ids = ['正确的用户名和正确的密码登录','正确的用户名和错误的密码登录','空的密码登录','空的用户名登录']
@pytest.fixture(params=cases,ids=ids)
def fixture_demo(request):
print("===初始化方法===")
yield request.param # request.param :代表将params接受到的数据返回给测试用例中。
print("===清除方法===")
# case1 : 输入正确的用户名和正确的密码进行登录
def test_login(fixture_demo):
# fixture_demo : 每次循环进来以后,都给到一组数据 ,而这组数据其实就是一个元组
print(fixture_demo)
expect_result = fixture_demo[0]
username = fixture_demo[1]
password = fixture_demo[2]
actual_result = login(username,password).get('code')
assert expect_result == actual_result
代码运行结果 :
参数3:testpaths
[pytest]
testpaths = test_001
运行结果如下:
参数4:addopts
以下这种是直接在命令中加入参数 :
如果将上面的参数配置到addopts中 ,具体配置如下 :
[pytest]
addopts = -sv --alluredir=./result --clean-alluredir
你将在命令行直接输入 :pytest test02_login.py
和上面加参数运行结果一样 。
参数5:python_files|python_class|python_functions
[pytest]
python_files = test_*.py
python_classes = Test*
python_functions = test*
通过这样编写 ,pyest搜索就会按照这个规则搜索测试用例 ,当然,其实我们这里修改的还是它默认的 。
参数6:norecursedirs
[pytest]
norecursedirs = test01
运行后将不会搜索该目录下的测试用例进行运行 。
参数7:log_cli
[pytest]
testpaths = test01
log_cli = True
log_file = ./log/test.log ; 日志存放路径
log_cli_level = INFO ; 日志等级
log_cli_format = %(asctime)s [%(levelname)s] | %(filename)s:%(lineno)s | %(message)s ;日志格式化
log_cli_date_format = %Y-%m-%d %H:%M:%S ;日志日期格式 。
运行结果后,可以在控制台下看到对应的日志格式 ,同时将日志文件输出到了log/test.log下 。
参数8:xfail_strict
接下来我们来看段代码 :
import pytest
from package_pytest.login import login
import sys
# case1 : 输入正确的用户名和正确的密码进行登录
@pytest.mark.xfail()
def test_login_success():
print("1")
expect_result = 0
actual_result = login('admin','123456').get('code')
assert expect_result == actual_result
# case2 : 输入正确的用户名和错误的密码进行登录
@pytest.mark.xfail()
def test_password_is_wrong():
print("2")
expect_reesult = 3
actual_result = login('admin','1234567').get('code')
assert expect_reesult == actual_result
# case3 : 输入用户名和空的密码进行登录
@pytest.mark.xfail()
def test_password_is_null():
print("3")
expect_reesult = 20
actual_result = login('admin', '').get('code')
assert expect_reesult == actual_result
不标记xfail时,第三条用例运行是失败的 ,前两条正常运行是正常的 ;标记上xfail时 , 运行的结果是以下这样的 :
================================================= test session starts ==================================================
platform win32 -- Python 3.6.4, pytest-7.0.1, pluggy-1.0.0 -- C:\Python36\python.exe
cachedir: .pytest_cache
rootdir: E:\python_project\python01_demo\package_pytest01, configfile: pytest.ini
plugins: allure-pytest-2.9.45, assume-2.4.3, forked-1.4.0, ordering-0.6, repeat-0.9.1, xdist-1.23.2
collected 3 items
test15_login_xfail.py::test_login_success 1
XPASS
test15_login_xfail.py::test_password_is_wrong 2
XPASS
test15_login_xfail.py::test_password_is_null 3
XFAIL
============================================ 1 xfailed, 2 xpassed in 0.05s =============================================
以前成功的变为xpassed ,而以前失败的变为xfailed了 。但如果加上以下的配置
[pytest]
xfail_strict = True
运行结果如下 ,你会发现,以前结果是xpassed的都变为failed 了 。
================================================= test session starts ==================================================
platform win32 -- Python 3.6.4, pytest-7.0.1, pluggy-1.0.0 -- C:\Python36\python.exe
cachedir: .pytest_cache
rootdir: E:\python_project\python01_demo\package_pytest01, configfile: pytest.ini
plugins: allure-pytest-2.9.45, assume-2.4.3, forked-1.4.0, ordering-0.6, repeat-0.9.1, xdist-1.23.2
collected 3 items
test15_login_xfail.py::test_login_success 1
FAILED
test15_login_xfail.py::test_password_is_wrong 2
FAILED
test15_login_xfail.py::test_password_is_null 3
XFAIL
======================================================= FAILURES =======================================================
__________________________________________________ test_login_success __________________________________________________
[XPASS(strict)]
________________________________________________ test_password_is_wrong ________________________________________________
[XPASS(strict)]
=============================================== short test summary info ================================================
FAILED test15_login_xfail.py::test_login_success
FAILED test15_login_xfail.py::test_password_is_wrong
============================================= 2 failed, 1 xfailed in 0.04s =============================================
1.conftest.py是什么 ?
conftest.py是fixture函数的一个集合,将一些前置动作放在fixture中,然后供其它测试用例调用。不同于普通被调用的模块,conftest.py使用时不需要导入,Pytest会首先查找这个文件。
2.conftest.py有什么作用?
那么它到底有什么使用场景呢 ? 执行用例前往往会做一些准备工作,而且都是一次性的操作 ,比如:
以上的这种一次性动作都可以放在conftest.py中的fixture中 。
3.conftest.py使用规则
4.需求 :在conftest.py中编写登录fixture且被自动调用
import pytest
# 实现登录 : 在执行测试用例前首先会被自动调用。
@pytest.fixture(scope='session',autouse=True)
def login():
"""
登录:请求方法,请求地址,请求体
:return:
"""
base = Base()
# 1.) 登录请求接口
login_url = base.get_url('/admin/auth/login')
# 2.) 获取响应体数据
result = base.post(login_url,LOGIN_INFO)
# 3.)判断是否登录成功
if not result.get('errno'):
logger.success("请求登录接口成功")
token = result.get('data').get('token') # 提取token值
cache.set('token',token) # 存放在缓存中了
else:
logger.error("登录失败:{}".format(result))
return result