pytest-setup&mark&skip&fixture&parametrize&xfail+converge

规则&setup

文件名规则: test_Name.py or name_test.py
类名规则:ClassName
方法名规则:test_Name

def setup_module():
    print("模块开始执行")


def teardown_module():
    print("模块结束执行")


def setup_function():
    print("每个模块级方法(不在类内)开始执行")


def teardown_function():
    print("每个模块级方法(不在类内)结束执行")


def test_function():
    print("模块级方法(不在类内)")


def test_function1():
    print("模块级方法(不在类内)1")


class TestClassName(object):
    def setup_class(self):
        print("类开始执行")

    def teardown_class(self):
        print("类结束执行")

    def setup_method(self):
        print("每个方法开始执行")

    def teardown_method(self):
        print("每个方法结束执行")

    def test_functionName(self):
        print(f"类方法")

scope 声明为fixture(测试准备/清理)方法

import pytest


@pytest.mark.level1
def test_level1(setup_session, setup_module, setup_func, setup_class):
    print(f"setup_session: {setup_session}")
    print(f"execute case level 1")


@pytest.mark.level2
def test_level2(setup_func, setup_module, setup_class, setup_session):
    print(f"execute case level 2")

@pytest.mark.level3
def test_level3():
    print(f"execute case level 3")

# autouse 自动调用fixture功能
@pytest.fixture(scope='function', autouse=True)  # 声明为fixture(测试准备/清理)方法
def setup_func():
    print("function start")
    yield
    print("function end")


@pytest.fixture(scope='module')  # 声明为fixture(测试准备/清理)方法
def setup_module():
    print("module start")
    yield
    print("module end")


@pytest.fixture(scope='class')  # 声明为fixture(测试准备/清理)方法
def setup_class():
    print("class start")
    yield
    print("class end")


@pytest.fixture(scope='session')  # 声明为fixture(测试准备/清理)方法
def setup_session():
    print("session start")
    yield 'session start'
    print("session end")

skip && skipif

import pytest

skip = False

@pytest.mark.skip
def test_skip():
    print("跳过此用例")

@pytest.mark.skipif(skip, reason="")
def test_skip():
    print("如果 skip 为 True 跳过此用例")

def test_function():
    print("function")

xfail

import pytest

"""
期望测试结果是的失败,但是不影响测试执行

"""


@pytest.mark.xfail
def test_xfail():
    print(f"功能尚未完成")

    assert 1 == 2

def test_fail():
    assert 1 == 2

mark

import pytest

"""
根据标签筛选脚本
"""

@pytest.mark.apple
def test_apple1():
    print("apple 1")

@pytest.mark.apple
def test_apple2():
    print("apple 2")

@pytest.mark.orange
def test_orange1():
    print("orange 1")

@pytest.mark.orange
def test_orange2():
    print("orange 2")

if __name__ == '__main__':
    # 执行标签为apple的用例
    # pytest.main(["-s", "-v", "test_mark.py", "-m=apple"])
    # 执行标签不为apple的用例
    # # pytest.main(["-s", "-v", "test_mark.py", "-m=not apple"])
    # 执行标签为apple或者orange的用例
    pytest.main(["-s", "-v", "test_mark.py", "-m=apple or orange"])

pytest.ini

[pytest]
markers=apple
    orange
log_cli_level = INFO
log_cli = 1

-k

import pytest

"""
筛选 类名和 方法名: 不区分大小写, 模糊匹配
"""


class TestApple():
    def test_apple(self):
        print("class Apple: apple")

    def test_orange(self):
        print("class Apple: orange")


class TestOrange():
    def test_orange(self):
        print("class Orange: orange")

    def test_apple(self):
        print("class Orange: apple")


if __name__ == '__main__':
    # # 类或者方法任意匹配到执行
    # pytest.main(["-s", "-v", "-k", "ple"])

    # 类 任意匹配 ple, 且方法不以test_a开头
    pytest.main(["-s", "-v", "-k", "ple and not test_a"])
    # 类 任意匹配 ple, 或者方法匹配到apple
    # pytest.main(["-s", "-v", "-k", "ple or apple"])

参数化

import pytest

"""
参数化

"""

class TestParametrize1():
    sumTestData = [(3, eval("1+2")),
                   (4, eval("1+3"))]

    @pytest.mark.parametrize("input,expect", sumTestData)
    def test_sum(self, input, expect):
        assert input == expect

class TestParametrize2():
    test_user_Data = [{'name': "lili", "age": 18}, {'name': "jack", "age": 20}]

    @pytest.fixture(scope="function")
    def login(self, request):
        name = request.param['name']
        age = request.param['age']
        print(f"login: {name}")
        return age

    # indirect = True ,login 作为方法调用
    @pytest.mark.parametrize("login", test_user_Data, indirect=True)
    def test_user(self, login):
        print(f"age : {login}")

class TestParametrize3():
    test_user_Data = [{'name': "lili", "age": 18}, {'name': "jack", "age": 20}]
    test_score_Data = [{'score': 89}, {'score': 90}]

    @pytest.fixture(scope="function")
    def login(self, request):
        name = request.param['name']
        age = request.param['age']
        print(f"login: {name}")
        return age

    @pytest.fixture(scope="function")
    def score(self, request):
        score = request.param['score']
        print(f"score: {score}")
        return score

    # indirect = True ,login 作为方法调用
    @pytest.mark.parametrize("score", test_score_Data, indirect=True)
    @pytest.mark.parametrize("login", test_user_Data, indirect=True)
    def test_user(self, login, score):
        assert score > 85

if __name__ == '__main__':
    # -x 遇到失败则停止
    # -maxfail 失败2个则停止
    pytest.main(["-s", "-v", "-x", "--maxfail", "2"])
    

coverage 测试覆盖度

import pytest
# 安装pytest-cov
pytest.main(["-s", "-v", dirname,
'--html=reports/report.html',
"--self-contained-html",
f"--cov={scriptPath}",
"--cov-report=html",
f"--cov-config=.coveragerc"
])
# --cov 代码路径
# --cov-config 跳过某些脚本的覆盖率测试

.coveragerc

[run]
omit =
    __init__.py
    */__init__.py

执行方式

if __name__ == '__main__':
    pytest.main(["-s", "-v", dirname, '--html=Outputs/reports/report.html'])
    # pytest.main(["-s", r"文件路径"]) # 执行文件的所有测试用例
    # pytest.main(["-s", r"文件路径::类名"]) # 执行文件的指定类的测试用例
    # pytest.main(["-s", r"文件路径::类名::方法名"]) # 执行文件的指定类指定方法的测试用例
    # pytest.main(["目录"]) # 搜目录所有测试用例
    #-m=xxx: 运行打标签的用例
	#-reruns=xxx,失败重新运行
	#-q: 安静模式, 不输出环境信息
	#-v: 丰富信息模式, 输出更详细的用例执行信息
	#-s: 显示程序中的print/logging输出
	#--resultlog=./log.txt 生成log
	#--junitxml=./log.xml 生成xml报告
	#--html=./clockOperation.html 生成html报告,需要插件pytest-html
	#-x: 遇到错误停止执行
	#--maxfil: 遇到几个错结束 --maxfil=3
    # --self-contained-html html 样式包含在html中
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值