pytest fixture及conftest详解三 (pytest.ini配置文件)

在这里插入图片描述


一、pytest.ini介绍

是pytest框架的主配置文件,实际生产中主要用来规范日志的格式或日志文件保存的位置,增加用例标签等等,总之简单易用,属于pytest学习的重要知识点。

特别注意:
pytest.ini文件命名不能修改,文件中第一行必须用【pytest】申明这是一个pytest的ini文件

二、自定义mark标签

我门在编写自动化测试用例时,会有各种类型的场景用例,我们又不想一次性运行全部,只想运行其中的几个,这时我们可以借助mark标签来管理测试用例,mark标签是任意取的,但是要避开Python和pytest关键字,运行标签用 - m 来运行,如:pytest -m div testcases/menus/test_menus1.py::TestMenus

特别注意:
多个标签要换行,且不能在顶格写,要有空格

在这里插入图片描述

1.案例:只执行div的测试用例

# encoding=utf-8
import pytest

class TestMenus:

    @pytest.mark.div
    def test_menu1(self):
        assert 1 == 1

    @pytest.mark.div
    @pytest.mark.add
    def test_menu2(self):
        assert 1 == 1

    def test_menu3(self):
        assert 2 == 5


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

执行命令行:

D:\project_development\api_pytest>pytest -vs -m div testcases/menus/test_menus1.py::TestMenus

执行测试结果

======================================================= test session starts =======================================================
platform win32 -- Python 3.9.6, pytest-5.2.1, py-1.10.0, pluggy-0.13.1
rootdir: D:\project_development\api_pytest, inifile: pytest.ini
plugins: allure-pytest-2.9.43, Faker-14.1.0, testreport-1.1.2
collected 3 items / 1 deselected / 2 selected                                                                                      

testcases/menus/test_menus1.py::TestMenus::test_menu1 ----这是前置方法----
PASSED
testcases/menus/test_menus1.py::TestMenus::test_menu2 PASSED----这是后置方法----



================================================= 2 passed, 1 deselected in 0.10s =================================================

2.注册标记来防止拼写错误

自定义标记可以简化测试工作,让我们用指定的标记运行某个测试子集。但是,标记很容易拼错,比如把@pytest.mark.smoke拼成@pytest.mark.somke,默认情况下。这不会引起程序错误。pytest会以为这是你创建的另一个标记。为了避免拼写错误。可以在pytest.ini文件里注册标记
标记完可以通过:pytest --markers 查看
在这里插入图片描述

案例1:注册标记使用正确

[pytest]
;python_files = check*
;python_functions = check*
;python_classes = CHECK*

markers =
    smoke: Run the smoke test functions for tasks project
    get: Run the test functions that test tasks.get()
    div
    add
addopts= -v -s --capture=no

test_menus.py

# encoding=utf-8
import pytest
import logging

class TestMenus:

    @pytest.mark.smoke
    def test_menu1(self):
        logging.info('执行测试用例1')
        assert 1 == 1


    @pytest.mark.smoke
    def test_menu2(self):
        logging.info('执行测试用例2')
        assert 1 == 1

    def test_menu3(self):
        logging.info('执行测试用例3')
        assert 2 == 5


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

执行命令:pytest -m smoke

collected 3 items / 1 deselected / 2 selected                                                                                      

testcases/menus/test_menus1.py::TestMenus::test_menu1 ----这是前置方法----

---------------------------------------------------------- live log call ----------------------------------------------------------
2022-10-30 10:41:22 [INFO] 执行测试用例1 (test_menus1.py:9)
PASSED
testcases/menus/test_menus1.py::TestMenus::test_menu2
---------------------------------------------------------- live log call ----------------------------------------------------------
2022-10-30 10:41:22 [INFO] 执行测试用例2 (test_menus1.py:15)
PASSED----这是后置方法----


================================================= 2 passed, 1 deselected in 0.13s =================================================


案例2:注册标记使用错误

执行命令:pytest -m smoke1(smoke1没有注册)
把smoke故意写错了,也没有报错,只是给我们一个警告,只需要我们在ini里注册下就不会有警告了

pytest -m smoke1
D:\project_development\api_pytest>pytest -m smoke1
======================================================= test session starts =======================================================
platform win32 -- Python 3.9.6, pytest-5.2.1, py-1.10.0, pluggy-0.13.1 -- d:\python3.9\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.9.6', 'Platform': 'Windows-10-10.0.19044-SP0', 'Packages': {'pytest': '5.2.1', 'pluggy': '0.13.1'}, 'Plugins
': {'allure-pytest': '2.9.43', 'Faker': '14.1.0', 'html': '3.2.0', 'metadata': '2.0.3', 'testreport': '1.1.2'}, 'JAVA_HOME': 'C:\\Pr
ogram Files\\Java\\jdk1.8.0_291'}
rootdir: D:\project_development\api_pytest, inifile: pytest.ini
plugins: allure-pytest-2.9.43, Faker-14.1.0, html-3.2.0, metadata-2.0.3, testreport-1.1.2
collected 3 items / 3 deselected                                                                                                   

====================================================== 3 deselected in 0.06s ======================================================


3.指定pytest忽略某些目录(norecurse)

pytest执行测试搜索时,会递归遍历所有子目录,包括某些你明知道没必要遍历的目录。遇到这种情况,你可以使用norecurse选项简化pytest的搜索工作。
在这里插入图片描述

pytest.ini
把menus用例目录注销了,不会去执行这个目录下的用例了

[pytest]

norecursedirs = .* venv menus *.egg dist build
url = https://blog.csdn.net/YZL40514131
markers =
    smoke: Run the smoke test functions for tasks project
    get: Run the test functions that test tasks.get()
    div
    add
addopts = -v -s --capture=no

log_cli = true
log_cli_level = info
log_cli_format = %(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)
log_cli_date_format = %Y-%m-%d %H:%M:%S
log_file = ./logs/all.log
log_file_level = info
log_file_format = %(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)
log_file_date_format = %Y-%m-%d %H:%M:%S

执行结果

collected 3 items                                                                                                                  

testcases/works/test_work1.py::TestWork::test_h ----这是前置方法----

读取到配置文件的url地址:https://blog.csdn.net/YZL40514131
用例:https://blog.csdn.net/YZL40514131
PASSED
testcases/works/test_work1.py::TestWork::test_work1 PASSED
testcases/works/test_work1.py::TestWork::test_work2 PASSED----这是后置方法----


======================================================== 3 passed in 0.14s ========================================================

也可以指定多个目录

norecursedirs = .* venv menus works *.egg dist build

4.指定测试目录(testpaths)

norecuredirs告诉pytest哪些路径不用访问,而testpaths则指示pytest去哪里访问。testpaths是一系列相对于根目录的路径,用于限定测试用例的搜索范围。只有在pytest未指定文件目录参数或测试用例标识符时,该选项才有作用

pytest.ini
如果我们只想执行testcases/menus下的测试用例,则可以把testcases/menus放到testpaths里

[pytest]

testpaths = testcases/menus
url = https://blog.csdn.net/YZL40514131
markers =
    smoke: Run the smoke test functions for tasks project
    get: Run the test functions that test tasks.get()
    div
    add
addopts = -v -s --capture=no

log_cli = true
log_cli_level = info
log_cli_format = %(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)
log_cli_date_format = %Y-%m-%d %H:%M:%S
log_file = ./logs/all.log
log_file_level = info
log_file_format = %(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)
log_file_date_format = %Y-%m-%d %H:%M:%S

执行命令

collected 3 items                                                                                                                  

testcases/menus/test_menus1.py::TestMenus::test_menu1 ----这是前置方法----

---------------------------------------------------------- live log call ----------------------------------------------------------
2022-10-30 11:34:00 [INFO] 执行测试用例1 (test_menus1.py:9)
PASSED
testcases/menus/test_menus1.py::TestMenus::test_menu2
---------------------------------------------------------- live log call ----------------------------------------------------------
2022-10-30 11:34:00 [INFO] 执行测试用例2 (test_menus1.py:15)
PASSED
testcases/menus/test_menus1.py::TestMenus::test_menu3
---------------------------------------------------------- live log call ----------------------------------------------------------
2022-10-30 11:34:00 [INFO] 执行测试用例3 (test_menus1.py:19)
PASSED----这是后置方法----


======================================================== 3 passed in 0.09s ========================================================

5.如果我既指定了testpaths和 norecursedirs ,而且两个是一样的,结果会怎样

在这里插入图片描述
从上面两次的运行结果可以看出,如果既指定了testpaths和 norecursedirs ,而且两个是一样的,则是按照testpaths执行的

collected 3 items                                                                                                                  

testcases/menus/test_menus1.py::TestMenus::test_menu1 ----这是前置方法----

---------------------------------------------------------- live log call ----------------------------------------------------------
2022-10-30 11:38:28 [INFO] 执行测试用例1 (test_menus1.py:9)
PASSED
testcases/menus/test_menus1.py::TestMenus::test_menu2
---------------------------------------------------------- live log call ----------------------------------------------------------
2022-10-30 11:38:28 [INFO] 执行测试用例2 (test_menus1.py:15)
PASSED
testcases/menus/test_menus1.py::TestMenus::test_menu3
---------------------------------------------------------- live log call ----------------------------------------------------------
2022-10-30 11:38:28 [INFO] 执行测试用例3 (test_menus1.py:19)
PASSED----这是后置方法----


======================================================== 3 passed in 0.09s ========================================================

三.自定义运行时的默认参数

pytest有多个经常使用的参数,如 - vs 来打印更详细的信息,但是每次都要手动输入很麻烦,例如上个案例 pytest -vs -m div testcases/menus/test_menus1.py::TestMenus
这是需要用到 addopts 配置默认运行参数

特别注意
addopts 运行时参数(可添加多个命令行参数,空格分隔,所有参数与命令行一致)

案例:

pytest.ini

[pytest]
markers =
    smoke: Run the smoke test functions for tasks project
    get: Run the test functions that test tasks.get()
    div
    add
addopts= -v -s

url = https://blog.csdn.net/YZL40514131

test_menus1.py

# encoding=utf-8
import pytest

class TestMenus:

    @pytest.mark.div
    def test_menu1(self):
        assert 1 == 1

    @pytest.mark.div
    @pytest.mark.add
    def test_menu2(self):
        assert 1 == 1

    def test_menu3(self):
        assert 2 == 5


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

命令行执行:pytest -m div testcases/menus/test_menus1.py::TestMenus

pytest -m div testcases/menus/test_menus1.py::TestMenus

执行结果

collected 3 items / 1 deselected / 2 selected                                                                                      

testcases/menus/test_menus1.py::TestMenus::test_menu1 ----这是前置方法----
PASSED
testcases/menus/test_menus1.py::TestMenus::test_menu2 PASSED----这是后置方法----


================================================= 2 passed, 1 deselected in 0.10s =================================================


四.格式化日志

案例

pytest.ini

[pytest]
markers =
    smoke: Run the smoke test functions for tasks project
    get: Run the test functions that test tasks.get()
    div
    add
addopts= -v -s --capture=no


log_cli = true
log_cli_level = info
log_cli_format = %(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)
log_cli_date_format = %Y-%m-%d %H:%M:%S
log_file = ./logs/all.log
log_file_level = info
log_file_format = %(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)
log_file_date_format = %Y-%m-%d %H:%M:%S

test_menus.py

# encoding=utf-8
import pytest
import logging

class TestMenus:

    @pytest.mark.div
    def test_menu1(self):
        logging.info('执行测试用例1')
        assert 1 == 1

    @pytest.mark.div
    @pytest.mark.add
    def test_menu2(self):
        logging.info('执行测试用例2')
        assert 1 == 1

    def test_menu3(self):
        logging.info('执行测试用例3')
        assert 2 == 5


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

执行命令:pytest testcases/menus/test_menus1.py::TestMenus

执行结果

testcases/menus/test_menus1.py::TestMenus::test_menu1 ----这是前置方法----

---------------------------------------------------------- live log call ----------------------------------------------------------
2022-10-29 23:37:46 [INFO] 执行测试用例1 (test_menus1.py:9)
PASSED
testcases/menus/test_menus1.py::TestMenus::test_menu2
---------------------------------------------------------- live log call ----------------------------------------------------------
2022-10-29 23:37:46 [INFO] 执行测试用例2 (test_menus1.py:15)
PASSED
testcases/menus/test_menus1.py::TestMenus::test_menu3
---------------------------------------------------------- live log call ----------------------------------------------------------
2022-10-29 23:37:46 [INFO] 执行测试用例3 (test_menus1.py:19)
FAILED----这是后置方法----


============================================================ FAILURES =============================================================
______________________________________________________ TestMenus.test_menu3 _______________________________________________________

self = <testcases.menus.test_menus1.TestMenus object at 0x00000173C6D7A760>

    def test_menu3(self):
        logging.info('执行测试用例3')
>       assert 2 == 5
E       assert 2 == 5
E         -2
E         +5

testcases\menus\test_menus1.py:20: AssertionError
-------------------------------------------------------- Captured log call --------------------------------------------------------
INFO     root:test_menus1.py:19 执行测试用例3
=================================================== 1 failed, 2 passed in 0.17s ===================================================

五.自定义测试文件命名规则

测试用例默认命名规则

除非pytest命令指定到测试用例文件,否则测试用例文件命名应该以 test_开头或者以_test结尾。
测试函数命名,测试类的方法命名应该以test_开头。
测试类命名应当以Test开头。
tips: 测试类的不应该有构造函数。

python_files 自定义测试文件命名规则
python_classes = Test_* 自定义测试类命名规则
python_functions= test_* check_* 自定义测试方法命名规则

在这里插入图片描述

pytest 框架可以通过pytest.ini配置文件自定义命名规则,在某些特定场景下可能会用到。

特别注意:
想控制多种文件类型,用空格隔开

案例

pytest.ini文件

[pytest]
python_files = check*
python_functions = check*
python_classes = CHECK*

markers =
    smoke: Run the smoke test functions for tasks project
    get: Run the test functions that test tasks.get()
    div
    add
addopts= -v -s --capture=no


log_cli = true
log_cli_level = info
log_cli_format = %(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)
log_cli_date_format = %Y-%m-%d %H:%M:%S
log_file = ./logs/all.log
log_file_level = info
log_file_format = %(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)
log_file_date_format = %Y-%m-%d %H:%M:%S

check_menus.py

# encoding=utf-8
import pytest
import logging

class CHECKclass:

    @pytest.mark.div
    def check_menu1(self):
        logging.info('执行测试用例1')
        assert 1 == 1

    @pytest.mark.div
    @pytest.mark.add
    def check_menu2(self):
        logging.info('执行测试用例2')
        assert 1 == 1

    def check_menu3(self):
        logging.info('执行测试用例3')
        assert 2 == 5


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

执行命令行:pytest

collected 3 items                                                                                                                  

testcases/menus/check_menus.py::CHECKclass::check_menu1 ----这是前置方法----

---------------------------------------------------------- live log call ----------------------------------------------------------
2022-10-30 00:23:49 [INFO] 执行测试用例1 (check_menus.py:9)
PASSED
testcases/menus/check_menus.py::CHECKclass::check_menu2
---------------------------------------------------------- live log call ----------------------------------------------------------
2022-10-30 00:23:49 [INFO] 执行测试用例2 (check_menus.py:15)
PASSED
testcases/menus/check_menus.py::CHECKclass::check_menu3
---------------------------------------------------------- live log call ----------------------------------------------------------
2022-10-30 00:23:49 [INFO] 执行测试用例3 (check_menus.py:19)
FAILED----这是后置方法----
  • 29
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 24
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码敲到头发茂密

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值