Frame--pytest框架

1. pytest介绍

1.1 介绍
官方文档:https://docs.pytest.org/en/latest/contents.html
中文文档:https://pan.baidu.com/s/1eRobXSLy9xhBG2aX0PH12w 提取码: ijhe
插件:http://plugincompat.herokuapp.com/
第三方库:https://pypi.org/search/?q=pytest
https://lvjunjie.cn/qa-study/pytest/pytest%E7%AE%80%E4%BB%8B.html
1.2 安装配置

pytest安装

pip install pytest


# 项目中生成文件,使用时直接安装文件
pip freeze > requirements.txt
pip install -r requirements.txt

pytest运行配置

pycharm中默认运行unittest,点击pycharm界面File--Settings--Tools--Python Integrated Tools下选择项目,修改testing运行方式pytest

2. pytest使用

2.1 前置后置

@pytest.fixture测试用例的环境准备与清理,相当于unittest中setUp/tearDown/setUpclass/tearDownclass

1. pytest前置后置处理函数默放在项目根目录下公共文件conftest.py文件中,且必须用@pytest.fixture()装饰器形式定义在函数上面

2.  默认参数:@pytest.fixture(scope="function", params=None, autouse=False)
  + scope
    function 默认, 可以不设置. 每个调用fixture的都会执行
    class  测试类调用时不论类中有多少用例只执行一次, 
    module 作用于选中的模块(.py文件), 近运行一次
    session 作用于整个session, 整个session仅运行一次
 + params
    list类型,默认None, 接收参数值,对于param里面的每个值,fixture都会去遍历执行一次.
 + autouse
    是否自动运行,默认为false, 为true时,对应级别下的所有测试函数都会调用fixture

3.  使用fixture
    方法1:设置autouse=True是默认运行
    方法2:在测试用例前使用@pytest.mark.usefixtures("method_name")调用,此方法无法传递参数
    方法3:在测试用例中作为参数传递,在测试函数中可接受该参数 def test_demo("method_name",...)

4. fixture函数中yield之前为前置,yield之后为后置。且yield可返回参数,也可为空	

5. 参考代码:https://blog.csdn.net/weixin_42038022/article/details/106851964

fixture调用方式

# conftest.py
@pytest.fixture()     # 默认scope="function"
def function_fixture_1():
    print('######单一测试用例开始前执行')
    yield
    print('单一测试用例结束后执行######')


@pytest.fixture()     # 默认scope="function"
def function_fixture_2():
    print('######单一测试用例开始前执行')
    n = 3
    yield n   
    print('单一测试用例结束后执行######')

# test_demo.py
# 方法二
@pytest.mark.usefixtures("function_fixture_1")
def test_subtractive_1(a=2, b=3):
    r = MathMethod().subtractive(x=a, y=b)
    assert r == -1

# 方法二
def test_subtractive_4(function_fixture_2, b=2):
    a = function_fixture_2
    r = MathMethod().subtractive(x=a, y=b)
    assert r == 1

前置中数据准备

# conftest.py

data = [(2, 3, 5), (1, 4, 5)]

@pytest.fixture(params=data)
def pre_data(request):
    return request.param

# test_demo.py
def test_data(pre_data):
    print(pre_data)

>
test_demo_2.py 
(2, 3, 5).
(1, 4, 5).
2.2 用例打标筛选

@pytest.mark.skip/xfail用于设置用例过滤筛选

@pytest.mark.skip(*, reason=None)      #无条件的跳过一个测试函数
@pytest.mark.skipif(condition, *, reason=None)   #条件为True时,跳过该测试函数,条件为False时,不跳过
@pytest.mark.xfail(condition=None, *, reason=None, raises=None, run=True, strict=False))   #条件为True时,试函数必定执行失败
@pytest.mark.demo        # demo为用例分类,如冒烟用例、新增用例等,执行是需要加上"-m demo"参数
@pytest.mark.skip    #无条件的跳过一个测试函数
def test_addition_1(a=2, b=3):

    r = MathMethod().addition(x=a, y=b)
    assert r == 5


@pytest.mark.skipif(2==2, reason="fail")   #条件为True时,跳过该测试函数
def test_addition_2(a=2, b=4):
    r = MathMethod().addition(x=a, y=b)
    assert r == 6


@pytest.mark.skipif(2==3, reason="fail")
def test_addition_3(a=2, b=8):
    r = MathMethod().addition(x=a, y=b)
    assert r == 10


@pytest.mark.xfail(2==2, reason="fail")    #条件为True时,函数失败
def test_addition_4(a=2, b=9):
    r = MathMethod().addition(x=a, y=b)
    assert r == 11
>
test_demo_1.py::test_addition_1 SKIPPED
test_demo_1.py::test_addition_2 SKIPPED
test_demo_1.py::test_addition_3 PASSED
test_demo_1.py::test_addition_4 XPASS
2.3 参数化

@pytest.mark.parametrize允许对测试函数或者测试类定义多个参数和fixtures的集合

# 数据驱动----参数化
@pytest.mark.parametrize('a, b, expected', [(2, 3, 5), (2, 4, 6), (3, 4, 7)])
def test_addition_1(a, b, expected):
    r = MathMethod().addition(x=a, y=b)
    assert r == expected
>
test_demo_1.py::test_addition_1[2-3-5] PASSED
test_demo_1.py::test_addition_1[2-4-6] PASSED
test_demo_1.py::test_addition_1[3-4-7] PASSED
2.4 命令行运行参数

自定义运行命令行参数

# conftest.py
def pytest_addoption(parser):
    parser.addoption(
        "--env",
        action="store",
        default="test",
        help="my test environment: test | pred | prod"
    )

@pytest.fixture
def cmdopt(request):
    return request.config.getoption("--env")

# test_demo.py
def test_cmd_env(cmdopt):
    assert cmdopt == 'test'
    assert cmdopt == 'prod'

if __name__ == '__main__':
    pytest.main(['-s', 'test_demo_2.py', '--env=test'])

>
assert cmdopt == 'test'
assert cmdopt == 'prod'
AssertionError: assert 'test' == 'prod'

命令行参数详解

-v 说明:可以输出用例更加详细的执行信息,比如用例所在的文件及用例名称等
-s 说明:控制台输出我们用例中的调式或log信息
-m ”标记“ 说明:执行特定的测试用例。我们再次修改一下我们的用例,并添加一个新的用例
-k "关键字" 说明:执行用例包含“关键字”的用例
-q 说明:简化控制台的输出
-x 说明:遇到错误时停止运行
-n m 说明:m个CPU或终端并行执行(插件pytest-xdist)
-x --maxfail=n 说明:当错误数达到n个时停止运行(pytest-rerunfailures )
--reruns 2 说明:运行失败后立即重运行n次
--reruns-delay 5 说明:每次重运行间隔n秒
if __name__ == '__main__':
    pytest.main(['-s', '-n 3', '--env=test', '--reruns=2', '--reruns-delay=5', 'test_demo.py'])
2.5 pytest-sugar
作用:运行时在控制台展示运行进度条,加强pytest运行过程中的进度可视化,其他没啥用。
使用:pip install pytest-sugar安装后重启pycharm即可,不行就多重启几次。
2.6 pytest-assume
作用:常规的assert断言失败之后当前用例会停止运行,导致后续的断言结果无法运行,pytest.assume断言失败后会继续运行后面的部分
def test_demo1():
    assert 1 + 2 == 3
    assert 1 + 3 == 3
    assert 1 + 4 == 2
    assert 1 + 4 == 5


def test_demo():
    pytest.assume(1 + 2 == 3)
    pytest.assume(1 + 3 == 3)
    pytest.assume(1 + 4 == 2)
    pytest.assume(1 + 4 == 5)

2.7 pytest-metadata

使用pytest 执行用例的时候加上 -v 参数(或–verbose),在控制台输出报告的头部就会输出元数据(metadata) 。感觉这个插件没啥用啊。

>pytest --verbose ============================= test session starts ============================= platform win32 -- Python 3.6.0, pytest-4.5.0, py-1.5.4, pluggy-0.13.1 -- e:\python36\python.exe cachedir: .pytest_cache metadata: {'Python': '3.6.0', 'Platform': 'Windows-10-10.0.17134-SP0', 'Packages': {'pytest': '4.5.0', 'py': '1.5.4', 'pluggy': '0.13.1'}, 'Plugins': {'allure-pytest': '2.8.6', 'PyTestReport': '0.1.9.3', 'assume': '2.2.1', 'forked': '0.2', 'html': '1.19.0', 'metadata': '1.7.0', 'ordering': '0.6', 'repeat': '0.7.0', 'rerunfailures': '8.0', 'xdist': '1.23.2'}, 'JAVA_HOME': 'D:\\java\\jdk1.8'} rootdir: D:\soft\code\pytest_api_2020_03 plugins: allure-pytest-2.8.6
2.8 pytest-ordering

pytest用例执行顺序

pytest用例执行过程中,先会收集用例和参数化参数,在收集用例时如果有skipif会优先执行这些逻辑,然后再执行fixture前置和用例。如果想在前置中准备数据,要使用参数接受的方法,否则会因为收集测试参数在数据准备之前导致前置准备的测试数据未被接受。
用例之间的顺序是文件之间按照ASCLL码排序,文件内的用例按照从上往下执行

pytest-ordering

作用:调整测试用例执行顺序
@pytest.mark.run(order=3)
def test_a():
    print('用例11111')
    assert True


@pytest.mark.run(order=2)
def test_b():
    print('用例22222')
    assert True


@pytest.mark.run(order=1)
def test_c():
    print('用例33333')
    assert True
>
用例33333.
用例22222.
用例11111.
2.9 pytest-html报告

安装

    pip install pytest-html

使用

生成JunitXML格式的测试报告:命令:--junitxml=path
生成result log格式的测试报告:命令:--resultlog=report\log.txt
生成Html格式的测试报告:命令:--html=report\test_one_func.html
eg:
    pytest.main([r"--html=Outputs\Reports\report.html", r"--junitxml=Outputs\Reports\report.xml"])
2.10 allure-pytest
  • allure 报告
# 安装
brew install allure
# 在测试执行期间收集结果
pytest -s -q --alluredir=./result/
# 测试完成后在线查看报告
allure serve ./result/

# 或生成html格式报告,并使用open命令查看。–clean目的是先清空测试再生成新的测试报告
allure generate ./result/ -o ./Output/allure_report --clean
allure open ./Output/allure_report

  • tomcat查看allure报告
# 启动tomcat服务,从结果生成报告
allure generate ./result/ -o ./report/ --clean   ## --clean 覆盖路径
# 打开报告
allure open -h 127.0.0.1 -p 8883 ./report/ 

更多高级allure功能,请查看官方文档https://docs.qameta.io/allure


9. pytest-jenkins集成
https://blog.csdn.net/akkzhjj/article/details/43990865
https://blog.csdn.net/qq_25672165/article/details/104945411
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值