pytest動態添加命令行參數並獲取命令行輸入的參數到程序中(鈎子函數:pytest_addoption)


Hook 方法之 pytest_addoption :

pytest_addoption 可以讓用戶注冊一個自定義的命令行參數,方便用戶將數據傳遞給pytest;

這個 Hook 方法一般和 內置 fixture pytestconfig 配合使用,pytest_addoption 注冊命令行參數,pytestconfig 通過配置對象讀取參數的值;

考慮場景:

  1. 我們的自動化用例需要支持在不同測試環境運行,有時候在dev環境運行,有時候在test環境運行;
  2. 有時候需要根據某個參數不同的參數值,執行不同的業務邏輯;

上面的場景我們都可以通過“在命令行中輸入參數,然后用例中接收這個參數,通過判斷這個參數的值來做不同的邏輯”來實現。那么我們的需求就變為pytest中如何自定義一個命令行參數呢?這時候我們就需要用到pytest的鈎子函數:pytest_addoption。

parser.addoption() 參數說明:

name:自定義命令行參數的名字,可以是:"foo""-foo""--foo";
action:在命令行中遇到此參數時要采取的基本操作類型;
nargs:應該使用的命令行參數的數量;
const:某些操作和nargs選擇所需的常量值;
default:如果參數不在命令行中,則生成的默認值。
type:命令行參數應該轉換為的類型;
choices:參數允許值的容器;
required:命令行選項是否可以省略(僅可選);
help:對參數作用的簡要說明;
metavar:用法消息中參數的名稱;
dest:要添加到 parse_args() 返回的對象中的屬性的名稱;

對parser.addoption() 參數解釋:

1. name:這個不用多說,自定義的參數的名字;

2. action 、default 和 const、help :

action="store":默認,只存儲參數的值,可以存儲任何類型的值,此時 default 也可以是任何類型的值,而且命令行參數多次使用也只能生效一個,最后一個值覆蓋之前的值;

# 注冊自定義參數 cmdopt 到配置對象
def pytest_addoption(parser):
    parser.addoption("--cmdopt", action="store",
                     default="這個是默認值...",
                     help="將命令行參數 ’--cmdopt' 添加到 pytest 配置中")
 
# 從配置對象中讀取自定義參數的值
@pytest.fixture(scope="session")
def cmdopt(request):
    return request.config.getoption("--cmdopt")
 
# 將自定義參數的值打印出來
@pytest.fixture(autouse=True)
def fix_1(cmdopt):
    print('\n --cmdopt的值:',cmdopt)
 
if __name__ == '__main__':
    # 使用參數
    pytest.main(['-s', '--cmdopt=98k'])

運行結果:

action="append":存儲一個列表,用 append 模式 將可以同時多次使用自定義參數,並且 default  默認值必須是一個列表,pytest 會把 default  默認參數的值和多個自定義參數的值放在一個列表中:

# 注冊自定義參數 cmdopt 到配置對象
def pytest_addoption(parser):
    parser.addoption("--cmdopt", action="append",
                     default=['這是默認參數'],
                     help="將命令行參數 ’--cmdopt' 添加到 pytest 配置中")
 
if __name__ == '__main__':
    # 使用參數
    pytest.main(['-s', '--cmdopt=98k', '--cmdopt=毛瑟小手槍'])

運行結果:

action="store_const":使用 const 為命令行參數指定一個常量值,必須和 const 參數同時使用,使用這個模式后命令行參數不能賦值:

def pytest_addoption(parser):
    parser.addoption("--cmdopt", action="store_const",
                     default='這是默認參數',
                     const='這個是為命令行參數指定的常量值...',
                     help="將命令行參數 ’--cmdopt' 添加到 pytest 配置中")
 
if __name__ == '__main__':
    pytest.main(['-s','--cmdopt'])

運行結果:

action="append_const":存儲一個列表,使用 const 為命令行參數指定一個常量值,並將 default 默認值和 const  常量值添加到列表中,這個模式可以同時多次使用自定義參數,但是還是不能賦值,只能使用常量;

def pytest_addoption(parser):
    parser.addoption("--cmdopt", action="append_const",
                     default=['這是默認參數'],
                     const='這個是為命令行參數指定的常量值...',
                     help="將命令行參數 ’--cmdopt' 添加到 pytest 配置中")
 
if __name__ == '__main__':
    pytest.main(['-s','--cmdopt', '--cmdopt'])

運行結果:

3. type:type 的類型可以是 python 的基礎類型,比如:int,str,float,list 等類型,如果不指定類型的話,pytest會把接受到的參數值都默認為 str 類型,所以我們有時需要指定參數的類型:

注意:在使用 type 指定類型時,也需要把 default 的類型修改為同樣的類型!

def pytest_addoption(parser):
    parser.addoption("--cmdopt", action="store",
                     default=100,
                     type=int,
                     help="將命令行參數 ’--cmdopt' 添加到 pytest 配置中")
 
if __name__ == '__main__':
    pytest.main(['-s', f'--cmdopt=888'])

運行結果:

4. choices:choices 可以指定幾個值,自定義參數必須在這幾個值中選擇一個,否則會報錯:

def pytest_addoption(parser):
    parser.addoption("--cmdopt", action="store",
                     default='100',
                     choices= ['python', 'java', 'c++'],
                     help="將命令行參數 ’--cmdopt' 添加到 pytest 配置中")
 
if __name__ == '__main__':
    pytest.main(['-s', f'--cmdopt=888'])

運行結果:

實戰舉例:

通過conftest.py配置

新建一個conftest.py文件,然后在conftest.py文件中通過pytest_addoption方法來添加命令行參數,通過定義的fixture來獲得參數的值。

# file_name: conftest.py


import pytest


def pytest_addoption(parser):
    parser.addoption(
        "--cmdopt", action="store", default="type1", help="my option: type1 or type2"
    )
    parser.addoption(
        "--env", action="store", default="dev", help="env:表示測試環境,默認dev環境"
    )


# 從配置對象中讀取自定義參數的值(一)
@pytest.fixture()
def cmdopt(pytestconfig):
    return pytestconfig.getoption("cmdopt")


# 從配置對象中讀取自定義參數的值(二)
@pytest.fixture()
def env(request):
    return request.config.getoption("--env")

上面conftest.py文件中新增了兩個命令行參數:--cmdopt和--env;然后定義了兩個fixture,在測試用例中想要獲得參數--cmdopt的值,就可以調用cmdopt函數;調用env函數可以獲取參數--env的值。

編寫測試用例:

# file_name: test_option.py

import pytest


def test_option(env):
    if env == 'dev':
        print("當前測試環境為:{},域名切換為開發環境".format(env))
    elif env == 'test':
        print("當前測試環境為:{},域名切換為測試環境".format(env))
    else:
        print("環境錯誤,當前環境{}不存在".format(env))


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

上面例子是獲取env的值,針對env值的不同做不同的操作。

不帶參數運行:

命令行中輸入指令: pytest test_option.py -s ,運行結果:

 因為我們在conftest.py文件中定義的參數env的默認值為dev,所以當運行時命令行不傳env參數,則使用默認值dev。

帶參數運行:

命令行中輸入指令: pytest test_option.py -s --env=test ,運行結果:

從結果中可以看到,命令行中輸入參數env=test,在測試用例中獲取到通過fixture獲取到env的值為test。

 


免責聲明!

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



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