pytest框架基础

1.生成时间戳的html报告

pytest 运行项目
import pytest
from datetime import datetime

获取时间戳,now()获取现在的时间,strftime()转化成字符串
report_time = datetime.now().strftime("%Y%m%d%H%M%S")
字符串拼接
filename = f'pyreport-{report_time}.html'
收集用例并运行用例
命令行参数放入列表中
pytest.main([f"--html={filename}"])

2.fixture夹具

实现夹具复用,就要封装,测试用例函数调用夹具时,就需要导入模块,但是每次都导入,容易出现错误,那么有没有一种方法可以实现不需要导入而自动读取呢?共享fixture的出现就解决了这个问题。

共享fixture的实现:

1)将所有的夹具全部放到一个固定的模块文件, conftest.py 文件名固定

conftest.py:

import pytest

声明这是一个夹具,这个夹具就是个函数
@pytest.fixture()
def fixt():
    # setUp
    print("每次测试都会执行的")
    # yield 分割线 前置和后置
    yield
    # tearDown
    print("每次测试用例后都会执行的")

2)所有导入夹具的操作就可以省略,pytest运行时会自动在 conftest.py中查找

测试用例:不需要进行导入操作

import pytest

class TestFixture:
    # 调用夹具
    def test_fixture(self, fixt):
        assert 1 + 1 == 2

class TestFixture1:
    # 调用夹具
    def test_fixture1(self, fixt):
        assert 1 + 1 == 2

运行结果:

pytest的夹具除了有共享fixture的特性外,还有非常灵活的作用域管理。

  • function
  • class
  • module
  • package
  • session

定义夹具conftest.py:

import pytest

声明这是一个夹具,这个夹具就是个函数
@pytest.fixture()
def fixt():
    # setUp
    print("每次测试都会执行的")
    # yield 分割线 前置和后置
    yield
    # tearDown
    print("每次测试用例后都会执行的")

@pytest.fixture()
def function_fixt():
    # setUp
    print("function_fixt start")
    # yield 分割线 前置和后置
    yield
    # tearDown
    print("function_fixt finished")

class级别必须定义scope='class'
@pytest.fixture(scope='class')
def class_fixt():
    # setUp
    print("class_fixt start")
    # yield 分割线 前置和后置
    yield
    # tearDown
    print("class_fixt finished")

module级别必须定义scope='module'
@pytest.fixture(scope='module')
def module_fixt():
    # setUp
    print("module_fixt start")
    # yield 分割线 前置和后置
    yield
    # tearDown
    print("module_fixt finished")

测试用例:

class TestFixtureFunction:
    def test_fixture_function(self, function_fixt, class_fixt,module_fixt):
        assert 1 + 1 == 2

    def test_fixture_function_2(self, function_fixt, class_fixt,module_fixt):
        assert 1 + 1 == 2

class TestFixtureFunction2:
    def test_fixture_function21(self, function_fixt, class_fixt,module_fixt):
        assert 1 + 1 == 2

    def test_fixture_function_22(self, function_fixt, class_fixt,module_fixt):
        assert 1 + 1 == 2

运行结果(从运行结果中我们可以知道不同作用域的夹具执行的顺序和次数):

从上例中可以看出,每次测试用例调用夹具时,还需要写上夹具的方法名称,有没有方法实现自动调用呢?

只需要在 conftest.py文件中封装夹具方法时,在声明中添加参数 autouse=True

import pytest

声明这是一个夹具,这个夹具就是个函数
@pytest.fixture(autouse=True)
def fixt():
    # setUp
    print("每次测试都会执行的")
    # yield 分割线 前置和后置
    yield
    # tearDown
    print("每次测试用例后都会执行的")

@pytest.fixture(scope='function', autouse=True)
def function_fixt():
    # setUp
    print("function_fixt start")
    # yield 分割线 前置和后置
    yield
    # tearDown
    print("function_fixt finished")

class级别必须定义scope='class'
@pytest.fixture(scope='class', autouse=True)
def class_fixt():
    # setUp
    print("class_fixt start")
    # yield 分割线 前置和后置
    yield
    # tearDown
    print("class_fixt finished")

module级别必须定义scope='module'
@pytest.fixture(scope='module', autouse=True)
def module_fixt():
    # setUp
    print("module_fixt start")
    # yield 分割线 前置和后置
    yield
    # tearDown
    print("module_fixt finished")

测试用例:

class TestFixtureFunction:
    def test_fixture_function(self):
        assert 1 + 1 == 2

    def test_fixture_function_2(self):
        assert 1 + 1 == 2

class TestFixtureFunction2:
    def test_fixture_function21(self):
        assert 1 + 1 == 2

    def test_fixture_function_22(self):
        assert 1 + 1 == 2

运行结果:

3.参数化parametrize

pytest的参数化和夹具与unittest不兼容。

import pytest

data = [1, 2, 3]

class TestParams:

    # info存储遍历data的结果
    @pytest.mark.parametrize('info', data)
    # 测试用例参数必须与声明中获取的变量同名即info
    def test_params(self, info):
        print(info)
        assert 1 + 1 == 2

运行结果:

实战当中会有两种模式:

模式1:

1,unittest编写用例,使用unittest ddt 和 夹具 setUp

2,pytest运行

模式2:

全部用pytest,完全舍弃unittest

4.用例筛选

  • 第一步,提前把标记名注册到 pytest 里面。

有两种方法:

1)pytest.ini文件中配置

[pytest]
markers =
    slow: marks tests as slow (deselect with '-m "not slow"')
    serial

2) pyproject.toml文件中配置

[tool.pytest.ini_options]
markers = [
    "slow: marks tests as slow (deselect with '-m \"not slow\"')",
    "serial",
]

如本例中是在pytest.ini(存放在项目目录下)进行配置:

[pytest]
markers =
    success
    login
  • 第二步,通过pytest在用例方法或者测试类上做一个标记;
import pytest

class TestMarker:
    # 调用夹具
    @pytest.mark.success
    def test_mark(self):
        assert 1 + 1 == 2

    def test_mark1(self):
        assert 1 + 1 == 2

@pytest.mark.success
class TestMarker1:
    # 调用夹具
    @pytest.mark.login
    def test_mark(self):
        assert 1 + 1 == 2

    def test_mark1(self):
        assert 1 + 1 == 2
  • 第三步,在运行用例时,通过标记执行。

进入目录

使用 pytest -m “success” (必须用双引号)指令运行有 success标记的测试类和测试方法。

使用 pytest -m “login and success”(必须用双引号)指令运行有 successlogin标记的测试类和测试方法。

使用 pytest -m “login or success”(必须用双引号)指令运行有 successlogin标记的测试类和测试方法。

标记支持逻辑运算 and or not ,如” not success” 反向执行。

Original: https://blog.csdn.net/Ly_LittleStar/article/details/121362235
Author: 胖困困
Title: pytest框架基础

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/772736/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球