第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Pytest:使用使用另一個夾具作為輸入的夾具參數(shù)化單元測試

Pytest:使用使用另一個夾具作為輸入的夾具參數(shù)化單元測試

我是參數(shù)化和固定裝置的新手,并且還在學(xué)習(xí)。我發(fā)現(xiàn)了一些使用間接參數(shù)化的帖子,但根據(jù)我的代碼中的內(nèi)容,我很難實(shí)現(xiàn)。我將不勝感激關(guān)于如何實(shí)現(xiàn)這一目標(biāo)的任何想法。我的 conftest.py 中有幾個固定裝置,它們?yōu)槲业臏y試文件中的函數(shù)“get_fus_output()”提供輸入文件。該函數(shù)處理輸入并生成兩個數(shù)據(jù)幀以在我的測試中進(jìn)行比較。此外,我將根據(jù)共同值 ('Fus_id') 轉(zhuǎn)租這兩個 DF 以單獨(dú)測試它們。所以這個函數(shù)的輸出將是 [(Truth_df1, test_df1),(Truth_df2, test_df2)...] 只是為了參數(shù)化每個測試和真值 df 的測試。不幸的是,我無法在我的測試函數(shù)“test_annotation_match”中使用它,因?yàn)檫@個函數(shù)需要一個夾具。我無法將夾具作為輸入提供給另一個夾具進(jìn)行參數(shù)化。是的,它在 pytest 中不受支持,但無法找出間接參數(shù)化的解決方法。#fixtures from conftest.py@pytest.fixture(scope="session")def test_input_df(fixture_path):    fus_bkpt_file = os.path.join(fixture_path, 'test_bkpt.tsv')    test_input_df= pd.read_csv(fus_bkpt_file, sep='\t')    return test_input_df@pytest.fixturedef test_truth_df(fixture_path):    test_fus_out_file = os.path.join(fixture_path, 'test_expected_output.tsv')    test_truth_df = pd.read_csv(test_fus_out_file, sep='\t')    return test_truth_df@pytest.fixturedef res_path():    return utils.get_res_path()#test script@pytest.fixturedef get_fus_output(test_input_df, test_truth_df, res_path):    param_list = []    # get output from script    script_out = ex_annot.run(test_input_df, res_path)    for index, row in test_input_df.iterrows():        fus_id = row['Fus_id']         param_list.append((get_frame(test_truth_df, fus_id), get_frame(script_out, fus_id)))        # param_list eg : [(Truth_df1, test_df1),(Truth_df2, test_df2)...]    print(param_list)    return param_list@pytest.mark.parametrize("get_fus_output", [test_input_df, test_truth_df, res_path], indirect=True)def test_annotation_match(get_fus_output):    test, expected = get_fusion_output    assert_frame_equal(test, expected, check_dtype=False, check_like=True)
查看完整描述

1 回答

?
DIEA

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超3個贊

我不是 100% 確定我理解你在這里試圖做什么,但我認(rèn)為你對參數(shù)化和固定裝置作用的理解是不正確的??雌饋砟趪L試使用固定裝置為您的測試創(chuàng)建參數(shù)列表,這并不是真正正確的方法(而且您這樣做的方式肯定行不通,正如您所看到的) .


為了全面解釋如何解決這個問題,首先,讓我介紹一下參數(shù)化和固定裝置的使用背景。


參數(shù)化

我不認(rèn)為這里有任何新內(nèi)容,只是為了確保我們在同一頁面上:


通常,在 Pytest 中,一個test_*函數(shù)就是一個測試用例:


def test_square():

    assert square(3) == 9

如果你想做相同的測試但使用不同的數(shù)據(jù),你可以編寫單獨(dú)的測試:


def test_square_pos():

    assert square(3) == 9


def test_square_frac():

    assert square(0.5) == 0.25


def test_square_zero():

    assert square(0) == 0


def test_square_neg():

    assert square(-3) == 9

這不是很好,因?yàn)樗`反了DRY原則。參數(shù)化是解決這個問題的方法。您可以通過提供測試參數(shù)列表將一個測試用例變成多個:


@pytest.mark.parametrize('test_input,expected',

                         [(3, 9), (0.5, 0.25), (0, 0), (-3, 9)])

def test_square(test_input, expected):

    assert square(test_input) == expected

固定裝置

Fixture 也與DRY代碼有關(guān),但方式不同。


假設(shè)您正在編寫一個 Web 應(yīng)用程序。您可能有多個測試需要連接到數(shù)據(jù)庫。您可以向每個測試添加相同的代碼以打開和設(shè)置測試數(shù)據(jù)庫,但這肯定是在重復(fù)您自己。比方說,如果您切換數(shù)據(jù)庫,則需要更新大量測試代碼。


夾具是允許您進(jìn)行一些可用于多個測試的設(shè)置(以及可能的拆卸)的功能:


@pytest.fixture

def db_connection():

    # Open a temporary database in memory

    db = sqlite3.connect(':memory:')

    # Create a table of test orders to use

    db.execute('CREATE TABLE orders (id, customer, item)')

    db.executemany('INSERT INTO orders (id, customer, item) VALUES (?, ?, ?)',

                   [(1, 'Max', 'Pens'),

                    (2, 'Rachel', 'Binders'),

                    (3, 'Max', 'White out'),

                    (4, 'Alice', 'Highlighters')])

    return db      


def test_get_orders_by_name(db_connection):

    orders = get_orders_by_name(db_connection, 'Max')

    assert orders = [(1, 'Max', 'Pens'),

                     (3, 'Max', 'White out')]


def test_get_orders_by_name_nonexistent(db_connection):

    orders = get_orders_by_name(db_connection, 'John')

    assert orders = []

修正你的代碼

好的,在了解了背景知識后,讓我們深入研究您的代碼。


第一個問題是你的@pytest.mark.parametrize裝飾器:


@pytest.mark.parametrize("get_fus_output", [test_input_df, test_truth_df, res_path], indirect=True)

這不是使用indirect. 就像測試可以參數(shù)化一樣,夾具也可以參數(shù)化。從文檔中看不是很清楚(在我看來),但這indirect只是參數(shù)化固定裝置的另一種方法。這與在另一個 fixture 中使用 fixture完全不同,這正是您想要的。


事實(shí)上,要get_fus_output使用test_input_df、test_truth_df和fixtures,您根本res_path不需要這條線。通常,如果沒有以其他方式使用(例如,由裝飾器),@pytest.mark.parametrize測試函數(shù)或夾具的任何參數(shù)都會自動假定為夾具。@pytest.mark.parametrize


所以,你現(xiàn)有的@pytest.mark.parametrize并沒有按照你的期望去做。那么你如何參數(shù)化你的測試呢?這會遇到更大的問題:您正在嘗試使用get_fus_output夾具為 . 創(chuàng)建參數(shù)test_annotation_match。這不是你可以用夾具做的事情。


Pytest運(yùn)行時,首先收集所有的測試用例,然后一個一個運(yùn)行。測試參數(shù)必須在收集階段準(zhǔn)備就緒,但 fixture 直到測試階段才會運(yùn)行。夾具內(nèi)的代碼無法幫助進(jìn)行參數(shù)化。您仍然可以通過編程方式生成參數(shù),但固定裝置不是這樣做的方法。


你需要做幾件事:


首先,將get_fus_output夾具轉(zhuǎn)換為常規(guī)函數(shù)。這意味著刪除@pytest.fixture裝飾器,但您還必須更新它以不使用test_input_df test_truth_df, 和res_path固定裝置。(如果沒有其他東西需要它們作為固定裝置,您可以將它們?nèi)哭D(zhuǎn)換為常規(guī)函數(shù),在這種情況下,您可能希望將它們放在它們自己的模塊之外,或者只是將它們移動到同一個測試腳本中。conftest.py)


然后,@pytest.mark.parametrize需要使用該函數(shù)來獲取參數(shù)列表:


@pytest.mark.parametrize("expected,test", get_fus_output())

def test_annotation_match(expected, test):

    assert_frame_equal(test, expected, check_dtype=False, check_like=True)


查看完整回答
反對 回復(fù) 2023-04-11
  • 1 回答
  • 0 關(guān)注
  • 248 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號