pytest修改測試用例執行順序(鈎子函數:pytest_collection_modifyitems)


前言

pytest默認執行用例是根據項目下的文件名稱按ascii碼去收集運行的;文件中的用例是從上往下按順序執行的。

pytest_collection_modifyitems 這個函數顧名思義就是收集測試用例、改變用例的執行順序的。

【嚴格意義上來說,我們在用例設計原則上用例就不要有依賴順序,這樣才能更好的體現出測試用例的意義。(測試用例的執行不需要按照順序來執行,而是隨即執行)】

1、Hook方法之  pytest_collection_modifyitems :

pytest_collection_modifyitems 是在用例收集完畢之后被調用,可以用來調整測試用例執行順序;
它有三個參數,分別是:

session:會話對象;
config:配置對象;
items:用例對象列表;改變items里面用例的順序就可以改變用例的執行順序了
這三個參數分別有不同的作用,都可以拿來單獨使用,修改用例執行順序主要是使用 items 參數【用例執行之前,收集到的測試用例會以元素對象的方式存放在用例對象列表items中】

 2、pytest_collection_modifyitems方法源碼:

def pytest_collection_modifyitems(session, config, items):
""" called after collection has been performed, may filter or re-order the items in-place. :param _pytest.main.Session session: the pytest session object :param _pytest.config.Config config: pytest config object :param List[_pytest.nodes.Item] items: list of item objects """

一、針對單個測試.py文件修改測試用例執行順序

首先准備三個測試用例:

import pytest
 
class TestDemoA:
 
    def test_A_001(self):
        pass
 
    def test_A_002(self):
        pass
 
    def test_A_003(self):
        pass
 
if __name__ == '__main__':
    pytest.main(['-s'])

正常情況下pytest 會按照從上到下的順序依次執行(模塊級會先以模塊名按ascii編碼進行排序):

使用pytest_collection_modifyitems修改單個測試文件中的用例執行順序

在 conftest.py 文件中 使用pytest_collection_modifyitems  鈎子方法:

# conftest.py
 
# 在收集完測試用例后才會執行
def pytest_collection_modifyitems(items):
    print('pytest 收集到的所有測試用例:\n',items)
 
if __name__ == '__main__':
    pytest.main(['-s'])

可以看到控制台中打印出來了收集到的三個測試用例的對象,而且是在測試用例執行之前便已經收集【先收集測試用例,然后執行測試用例】

在執行完  pytest_collection_modifyitems  之后才顯示收集到了 3 個用例;

如果我們在  pytest_collection_modifyitems  中對用例進行調整,便會影響用例是否執行和執行順序;
 

利用 items 獲取收集到的用例名和用例節點:

# conftest.py
 
def pytest_collection_modifyitems(items):
    print('pytest 收集到的所有測試用例:\n', items)
    for item in items:
        print('---' * 10)
        print('用例名:', item.name)
        print('用例節點:', item.nodeid)
 
if __name__ == '__main__':
    pytest.main(['-s'])

運行結果:

修改用例執行順序和剔除測試用例:

# conftest.py
 
def pytest_collection_modifyitems(items):
    # 將用例名拿出來存入新列表new_items
    new_items = []
    for item in items:
        new_items.append(item.name)
 
    # 1. 刪除 test_A_002 用例
    # 獲取 test_A_002 在新列表的索引
    index_2 = new_items.index('test_A_002')
    # 在老列表中刪除這個索引
    del items[index_2]
    del new_items[index_2]  # 新列表同步刪除,和老列表保持同步
 
    # 2. 調換 1 和 3 的順序
    # 獲取 1 和 3 在新列表的索引
    index_1 = new_items.index('test_A_001')
    index_3 = new_items.index('test_A_003')
    # 根據索引在老列表中調換位置
    items[index_1], items[index_3] = items[index_3], items[index_1]

運行結果:

可以看到控制台輸出的結果中,用例3和用例1的順序調換了,用例2由於被刪除所以沒有執行;

代碼寫的比較粗糙,但是思路就是這樣:想辦法干涉 items列表中用例對象的排序;

二、針對多個測試.py文件

pytest默認執行順序

先設計一個簡單的 pytest 項目,有a和b兩個包,分別在 test_a.py 和 test_b.py 寫測試用例

 conftest.py內容:

import pytest

def pytest_collection_modifyitems(session, items):
    print("收集到的測試用例:%s"%items)

test_a.py內容:

def test_a_1():
    print("測試用例a_1")

def test_a_2():
    print("測試用例a_2")

test_b.py內容:

def test_b_2():
    print("測試用例b_2")

def test_b_1():
    print("測試用例b_1")

運行完成后可以看到收集到的測試用例【會在測試用例開始執行前收集】:

從結果可以看出運行的時候先按模塊名稱ascii碼去收集單個py文件里面的用例按從上到下寫的順序收集

items用例排序

如果我想改變上面的用例執行順序,以所有用例名稱ascii碼排序(測試方法名)。

先獲取到收集的用例的名稱,以用例名稱排序就可以了。

def pytest_collection_modifyitems(session, items):
    print(type(items))
    print("收集到的測試用例:%s" % items)
    # sort排序,根據用例名稱item.name的ASCII碼排序
    items.sort(key=lambda x: x.name)
    print("排序后的用例:%s" % items)
    for item in items:
        print("用例名:%s" % item.name)

重新執行后結果:

重新排序后就可以按用例的名稱ascii碼順序執行了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM