pytest 多个PY文件执行时共享变量及用fixture和conftest

Posted BreakCircle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pytest 多个PY文件执行时共享变量及用fixture和conftest相关的知识,希望对你有一定的参考价值。

 

1.pytest需要测试多个py文件,这些文件有一定的依赖关系,同时执行的时候,需要只执行一次初始化setup,结束再执行一次teardown;

2.多个py文件需要使用pytest的conftest.py,这个文件名是固定的,在同级目录还需要__init__.py;

3.由于setup这种经典的初始化方法只支持module,class.method,function,setup

  module: 一个py文件只运行一次,里面可以是class和function;

  class: 每个class执行一次;

  method: class里面的每个函数执行一次;

  function : 每个函数执行一次(函数不在class中);

  setup: 最小层级,每个函数运行一次;在allure报告中,现在在Test body中;其他级别显示在的setup中;

4.经典初始化不支持多个py初始化,只能选用fixture;

  scope值 :默认是function;

  session 多个py文件;

  module 一个py文件里面多个class或function;

  class: class级别;

  function:函数级别;

       由于我们是多个py所以,只能选择session;

       yield 是setup和teardown分界线;

@pytest.fixture(scope="session")
def start_up_session():
    try:
        
        case_name = os.path.basename(__file__).replace(\'.py\', \'\')
        print(case_name + " start")
        # yield 前面的是tearup的操作
        yield case_name
        # yield 后面的是teardown的操作
        print(case_name + " finish")

 

 

  autouse = True   fixture里面有个参数autouse,默认是Fasle没开启的,可以设置为True开启自动使用fixture功能,这样用例就不用每次都去传参了;

 

@pytest.fixture(scope="function", autouse=True)
def get_status():
    case_name = os.path.basename(os.path.abspath(__file__)).replace(".py", "")
    print(case_name + " begin")
    yield 1 if case_name.isalnum() else 0
    print(case_name + " finish")

# 不传参数get_tstus也会运行
def test_1(): print(1111) def test_name(): print(2222) if __name__ == "__mian__": pytest.main(["-s", "test_base.py"]) ========================================= ============================= test session starts ============================= platform win32 -- Python 3.6.8, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- C:\\Program Files\\Python36\\python.exe cachedir: .pytest_cache metadata: {\'Python\': \'3.6.8\', \'Platform\': \'Windows-10-10.0.18362-SP0\', \'Packages\': {\'pytest\': \'5.4.2\', \'py\': \'1.8.1\', \'pluggy\': \'0.13.1\'}, \'Plugins\': {\'allure-pytest\': \'2.8.13\', \'cov\': \'2.8.1\', \'forked\': \'1.1.3\', \'html\': \'2.1.1\', \'metadata\': \'1.9.0\', \'ordering\': \'0.6\', \'rerunfailures\': \'9.0\', \'timeout\': \'1.3.4\', \'xdist\': \'1.32.0\'}, \'JAVA_HOME\': \'C:\\\\Program Files\\\\Java\\\\jdk1.8.0_202\'} rootdir: F:\\ShenjuCloudTest\\APP plugins: allure-pytest-2.8.13, cov-2.8.1, forked-1.1.3, html-2.1.1, metadata-1.9.0, ordering-0.6, rerunfailures-9.0, timeout-1.3.4, xdist-1.32.0 collecting ... collected 2 items test_base.py::test_1 test_base begin PASSED [ 50%]1111 test_base finish test_base.py::test_name test_base begin PASSED [100%]2222 test_base finish ============================== 2 passed in 0.03s ============================== Process finished with exit code 0

 

 autouse = True   fixture里面有个参数autouse,默认是Fasle没开启的,需要显示调用;

import pytest
import os

# 默认autouse=Fasle
@pytest.fixture(scope="function")
def get_status():
    case_name = os.path.basename(os.path.abspath(__file__)).replace(".py", "")
    print(case_name + " begin")
    yield 1 if case_name.isalnum() else 0
    print(case_name + " finish")

# 显式调用
@pytest.mark.usefixtures("get_status")
def test_1():
    print(1111)

# 显式调用
@pytest.mark.usefixtures("get_status")
def test_name():
    print(2222)


if __name__ == "__mian__":
    pytest.main(["-s", "test_base.py"])

 

5.fixture 需要返回值:用传参数调用:在函数参数中,插入fixture的参数;

import pytest
import os


@pytest.fixture(scope="function", autouse=True)
def get_status():
    case_name = os.path.basename(os.path.abspath(__file__)).replace(".py", "")
    print(case_name + " begin")
    yield 1 if case_name.isalnum() else 0
    print(case_name + " finish")


def test_1(get_status):
    num = get_status
    assert num == 0
    print(1111)


def test_name(get_status):
    num = get_status
    assert num < 1
    print(2222)


if __name__ == "__mian__":
    pytest.main(["-s", "test_base.py"])
===================================

============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- C:\\Program Files\\Python36\\python.exe
cachedir: .pytest_cache
metadata: {\'Python\': \'3.6.8\', \'Platform\': \'Windows-10-10.0.18362-SP0\', \'Packages\': {\'pytest\': \'5.4.2\', \'py\': \'1.8.1\', \'pluggy\': \'0.13.1\'}, \'Plugins\': {\'allure-pytest\': \'2.8.13\', \'cov\': \'2.8.1\', \'forked\': \'1.1.3\', \'html\': \'2.1.1\', \'metadata\': \'1.9.0\', \'ordering\': \'0.6\', \'rerunfailures\': \'9.0\', \'timeout\': \'1.3.4\', \'xdist\': \'1.32.0\'}, \'JAVA_HOME\': \'C:\\\\Program Files\\\\Java\\\\jdk1.8.0_202\'}
rootdir: F:\\ShenjuCloudTest\\APP
plugins: allure-pytest-2.8.13, cov-2.8.1, forked-1.1.3, html-2.1.1, metadata-1.9.0, ordering-0.6, rerunfailures-9.0, timeout-1.3.4, xdist-1.32.0
collecting ... collected 2 items

test_base.py::test_1 test_base begin
PASSED                                              [ 50%]1111
test_base finish

test_base.py::test_name test_base begin
PASSED                                           [100%]2222
test_base finish

6.fixture 不需要返回值:除了用传参数调用,还可以用@pytest.mark.usefixtures();对class和函数都可以使用,记得和scope搭配;

import pytest
import os


@pytest.fixture(scope="function", autouse=True)
def get_status():
    case_name = os.path.basename(os.path.abspath(__file__)).replace(".py", "")
    print(case_name + " begin")
    yield 1 if case_name.isalnum() else 0
    print(case_name + " finish")

@pytest.mark.usefixtures("get_status")
def test_1():
    print(1111)

@pytest.mark.usefixtures("get_status")
def test_name():
    print(2222)


if __name__ == "__mian__":
    pytest.main(["-s", "test_base.py"])
=======================================
============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- C:\\Program Files\\Python36\\python.exe
cachedir: .pytest_cache
metadata: {\'Python\': \'3.6.8\', \'Platform\': \'Windows-10-10.0.18362-SP0\', \'Packages\': {\'pytest\': \'5.4.2\', \'py\': \'1.8.1\', \'pluggy\': \'0.13.1\'}, \'Plugins\': {\'allure-pytest\': \'2.8.13\', \'cov\': \'2.8.1\', \'forked\': \'1.1.3\', \'html\': \'2.1.1\', \'metadata\': \'1.9.0\', \'ordering\': \'0.6\', \'rerunfailures\': \'9.0\', \'timeout\': \'1.3.4\', \'xdist\': \'1.32.0\'}, \'JAVA_HOME\': \'C:\\\\Program Files\\\\Java\\\\jdk1.8.0_202\'}
rootdir: F:\\ShenjuCloudTest\\APP
plugins: allure-pytest-2.8.13, cov-2.8.1, forked-1.1.3, html-2.1.1, metadata-1.9.0, ordering-0.6, rerunfailures-9.0, timeout-1.3.4, xdist-1.32.0
collecting ... collected 2 items

test_base.py::test_1 test_base begin
PASSED                                              [ 50%]1111
test_base finish

test_base.py::test_name test_base begin
PASSED                                           [100%]2222
test_base finish

 7. 多个py文件使用conftest.py,名字固定,不要改;

  同级需要有__init__.py;

  千万不要通过import导入conftest,否则每个py文件都会运行一遍conftest.py, 无法起到多个py只执行一次作用;pytest执行的时候自动去读conftest.py配置;

 

 

 

 

import pytest
import os

# conftest.py

@pytest.fixture(scope="session")
def get_status():
    case_name = os.path.basename(os.path.abspath(__file__)).replace(".py", "")
    print(case_name + " begin")
    yield 1 if case_name.isalnum() else 0
    print(case_name + " finish")
import pytest
import os

# test_base 不传参数,不要返回值

@pytest.mark.usefixtures("get_status")
def test_1():
    print(1111)


@pytest.mark.usefixtures("get_status")
def test_name():
    print(2222)


if __name__ == "__mian__":
    pytest.main(["-s", "test_base.py"])
====================================================================

============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- C:\\Program Files\\Python36\\python.exe
cachedir: .pytest_cache
metadata: {\'Python\': \'3.6.8\', \'Platform\': \'Windows-10-10.0.18362-SP0\', \'Packages\': {\'pytest\': \'5.4.2\', \'py\': \'1.8.1\', \'pluggy\': \'0.13.1\'}, \'Plugins\': {\'allure-pytest\': \'2.8.13\', \'cov\': \'2.8.1\', \'forked\': \'1.1.3\', \'html\': \'2.1.1\', \'metadata\': \'1.9.0\', \'ordering\': \'0.6\', \'rerunfailures\': \'9.0\', \'timeout\': \'1.3.4\', \'xdist\': \'1.32.0\'}, \'JAVA_HOME\': \'C:\\\\Program Files\\\\Java\\\\jdk1.8.0_202\'}
rootdir: F:\\ShenjuCloudTest\\APP
plugins: allure-pytest-2.8.13, cov-2.8.1, forked-1.1.3, html-2.1.1, metadata-1.9.0, ordering-0.6, rerunfailures-9.0, timeout-1.3.4, xdist-1.32.0
collecting ... collected 2 items

test/test_base.py::test_1 conftest begin
PASSED [ 50%]1111

test/test_base.py::test_name PASSED [100%]2222
conftest finish


============================== 2 passed in 0.03s ==============================

Process finished with exit code 0

import pytest
import os

# test_base1 传参数,需要返回值;
def test_1(get_status):
    print("test_1" + str(get_status))
    print(1111)


def test_name(get_status):
    print("test_name" + str(get_status))
    print(2222)


if __name__ == "__mian__":
    pytest.main(["-s", "test_base.py"])
==========================================
============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- C:\\Program Files\\Python36\\python.exe
cachedir: .pytest_cache
metadata: {\'Python\': \'3.6.8\', \'Platform\': \'Windows-10-10.0.18362-SP0\', \'Packages\': {\'pytest\': \'5.4.2\', \'py\': \'1.8.1\', \'pluggy\': \'0.13.1\'}, \'Plugins\': {\'allure-pytest\': \'2.8.13\', \'cov\': \'2.8.1\', \'forked\': \'1.1.3\', \'html\': \'2.1.1\', \'metadata\': \'1.9.0\', \'ordering\': \'0.6\', \'rerunfailures\': \'9.0\', \'timeout\': \'1.3.4\', \'xdist\': \'1.32.0\'}, \'JAVA_HOME\': \'C:\\\\Program Files\\\\Java\\\\jdk1.8.0_202\'}
rootdir: F:\\ShenjuCloudTest\\APP\\test
plugins: allure-pytest-2.8.13, cov-2.8.1, forked-1.1.3, html-2.1.1, metadata-1.9.0, ordering-0.6, rerunfailures-9.0, timeout-1.3.4, xdist-1.32.0
collecting ... collected 2 items

test_base1.py::test_1 conftest begin
PASSED                                             [ 50%]test_11
1111

test_base1.py::test_name PASSED                                          [100%]test_name1
2222
conftest finish


============================== 2 passed in 0.05s ==============================

 

以上是关于pytest 多个PY文件执行时共享变量及用fixture和conftest的主要内容,如果未能解决你的问题,请参考以下文章

python学习-pytest-fixture

pytest_01_安装和入门

pytest----fixture--使用fixture执行配置及销毁逻辑

python测试框架:如何执行pytest测试用例

Pytest之参数化

接口自动化之pytest——用例设计原则及执行顺序