1. 程式人生 > 其它 >Python測試框架pytest(08)fixture - conftest.py、yield、addfinalizer

Python測試框架pytest(08)fixture - conftest.py、yield、addfinalizer

1、conftest.py作用範圍

conftest.py 檔名稱是固定的,pytest 會自動識別該檔案,可以理解成一個專門存放 fixture 的配置檔案。

一個工程下可以建多個 conftest.py 的檔案,一般在工程根目錄下設定的 conftest 檔案起到全域性作用。在不同子目錄下也可以放 conftest.py 的檔案,作用範圍只能在該層級以及以下目錄生效。

conftest.py 配置 fixture 注意事項:

  • pytest 會預設讀取 conftest.py 裡面的所有 fixture。

  • conftest.py 檔名稱是固定的,不能改動。

  • conftest.py 只對同一個 package 下的所有測試用例生效。

  • 不同目錄可以有自己的 conftest.py,一個專案中可以有多個 conftest.py。

  • 測試用例檔案中不需要手動 import conftest.py,pytest 會自動查詢。

示例:

目錄結構:

1、My_pytest_Demo/conftest.py

指令碼程式碼:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公眾號:AllTests軟體測試
"""

import pytest

@pytest.fixture(scope='session', autouse=True)
def login():
    
print("====準備登入====")

2、My_pytest_Demo/fixture_chapter/conftest.py

指令碼程式碼:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公眾號:AllTests軟體測試
"""

import pytest

@pytest.fixture(scope='session', autouse=True)
def bai_du():
    print("====登入成功====")

3、My_pytest_Demo/fixture_chapter/login_demo.py

指令碼程式碼:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公眾號:AllTests軟體測試
"""

import pytest

class TestCase:
    def test_case(self):
        print("====執行用例====")

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

4、執行結果:

執行login_demo.py檔案,根目錄下的conftest.py先執行,之後執行fixture_chapter目錄下的conftest.py,最後才執行login_demo.py

2、yield實現teardown

前面章節講的其實都是 setup 的操作,接下來講解怎樣來實現 teardown 的操作。

用 fixture 實現 teardown 並不是一個獨立的函式,而是用 yield 關鍵字來開啟 teardown 操作。

  • 當 pytest.fixture(scope="session")時,作用域是整個測試會話,即開始執行 pytest 到結束測試只會執行一次。

  • 當 pytest.fixture(scope="function") 時,pytest 的 yield 類似 unittest 的 teardown。每個方法(函式)都會執行一次。

  • 當 pytest.fixture(scope="module")時,module 作用是整個 .py 檔案都會生效(整個檔案只會執行一次),用例呼叫時,引數寫上函式名稱就可以。

1、建立test_fixture4.py檔案

指令碼程式碼:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公眾號:AllTests軟體測試
"""
import pytest

@pytest.fixture(scope="session")
def open():
    # 會話前置操作setup
    print("===開啟瀏覽器open===")
    yield
    # 會話後置操作teardown
    print("===關閉瀏覽器open===")

@pytest.fixture
def login(open):
    # 方法級別前置操作setup
    print("===登陸操作login===")
    name = "===賬號==="
    pwd = "===密碼==="
    # 返回變數
    yield name, pwd
    # 方法級別後置操作teardown
    print("===登入成功login===")

def test_case1(login):
    print("===測試用例1===")
    # 返回的是一個元組
    print(login)
    # 分別賦值給不同變數
    name, pwd = login
    print(name, pwd)
    assert "賬號" in name
    assert "密碼" in pwd

def test_case2(login):
    print("===測試用例2===")
    print(login)

2、執行結果:

注意要點:

  • 如果 yield 前面的程式碼,即 setup 部分已經丟擲異常,則不會執行 yield 後面的 teardown 內容。

  • 如果測試用例丟擲異常,yield 後面的 teardown 內容還是會正常執行。

3、yield+with的結合

yield 也可以配合 with 語句使用。

建立test_fixture5.py檔案

指令碼程式碼:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公眾號:AllTests軟體測試
"""
import pytest
import smtplib

@pytest.fixture(scope="module")
def smtp_connection():
    with smtplib.SMTP("smtp.gmail.com", 587, timeout=5) as smtp_connection:
        yield smtp_connection

4、addfinalizer終結函式

除了 yield 可以實現 teardown,在 request-context 物件中註冊 addfinalizer 方法也可以實現終結函式。

1、建立test_fixture6.py檔案

在用法上,addfinalizer 跟 yield 是不同的,需要你去註冊作為終結器使用的函式。例如:增加一個函式 fin,並且註冊成終結函式。

指令碼程式碼:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公眾號:AllTests軟體測試
"""
import pytest

@pytest.fixture(scope="module")
def test_addfinalizer(request):
    # 前置操作setup
    print("===開啟瀏覽器===")
    test = "test_addfinalizer"

    def fin():
        # 後置操作teardown
        print("===關閉瀏覽器===")

    request.addfinalizer(fin)
    # 返回前置操作的變數
    return test

def test_case(test_addfinalizer):
    print("===最新用例===", test_addfinalizer)

2、執行結果:

yield 與 addfinalizer 的區別:

1、addfinalizer 可以註冊多個終結函式。

建立test_fixture_7.py檔案

指令碼程式碼:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公眾號:AllTests軟體測試
"""
import pytest

@pytest.fixture()
def demo_addfinalizer(request):
    print("====setup====")
    def fin1():
        print("====teardown1====")
    def fin2():
        print("====teardown2====")
    def fin3():
        print("====teardown3====")

    # 註冊demo_addfinalizer為終結函式
    request.addfinalizer(fin1)
    request.addfinalizer(fin2)
    request.addfinalizer(fin3)

def test_case1(demo_addfinalizer):
    print("====執行用例test_case1====")

def test_case2(demo_addfinalizer):
    print("====執行用例test_case2====")

def test_case3(demo_addfinalizer):
    print("====執行用例test_case3====")

執行結果:

註冊的3個函式都被執行了,但是要注意的是執行順序,與註冊的順序相反。

2、當setup的程式碼執行錯誤,addfinalizer依舊會執行。

本文來自部落格園,作者:AllTests軟體測試,轉載請註明原文連結:https://www.cnblogs.com/alltests/p/15428963.html