簡體   English   中英

pytest 是否支持在測試文件中使用 function 工廠?

[英]Does pytest support the use of function factories in test files?

示例test.py文件:

import torch

def one():
    return torch.tensor(0.0132005215)

def two():
    return torch.tensor(4.4345855713e-05)

def three():
    return torch.tensor(7.1525573730e-07)


def test_method(method, expected_value):
    value = method()
    assert(torch.isclose(value, expected_value))

def test_one():
    test_method(one, torch.tensor(0.0132005215))

def test_two():
    test_method(two, torch.tensor(4.4345855713e-05))

def test_three():
    test_method(three, torch.tensor(7.1525573730e-07))
    # test_method(three, torch.tensor(1.0))

if __name__ == '__main__':
    test_one()
    test_two()
    test_three()

基本上,我有幾個要測試的函數(這里稱為onetwothree ),它們都具有相同的簽名但內部結構不同。 因此,我沒有編寫函數test_one()test_two()等並因此復制代碼,而是編寫了一個“函數工廠”(這是正確的術語嗎?) test_method ,它將 function 作為輸入,預期結果並返回assert命令的結果。

如您所見,現在測試是手動執行的:我運行腳本test.py ,查看屏幕,如果沒有打印Assertion error ,我很高興。 當然,我想通過使用pytest來改進這一點,因為有人告訴我它是最簡單和最常用的 Python 測試框架之一。 問題是,通過查看pytest 文檔,我得到的印象是pytest將嘗試運行名稱以test_開頭的所有函數。 當然,測試test_method本身沒有任何意義。 你能幫我重構這個測試腳本,以便我可以用pytest運行它嗎?

在 pytest 中,您可以使用測試參數化來實現這一點。 在您的情況下,您必須為測試提供不同的參數:

import pytest

@pytest.mark.parametrize("method, expected_value",
                         [(one, 0.0132005215),
                          (two, 4.4345855713e-05),
                          (three, 7.1525573730e-07)])
def test_method(method, expected_value):
    value = method()
    assert(torch.isclose(value, expected_value))

If you run python -m pytest -rA (see the documentation for output options), you will get the output of three tests, something like:

======================================================= PASSES ========================================================
=============================================== short test summary info ===============================================
PASSED test.py::test_method[one-0.0132005215]
PASSED test.py::test_method[two-4.4345855713e-05]
PASSED test.py::test_method[three-7.152557373e-07]
================================================== 3 passed in 0.07s ==================================================

如果您不喜歡燈具名稱,可以調整它們:

@pytest.mark.parametrize("method, expected_value",
                          [(one, 0.0132005215),
                          (two, 4.4345855713e-05),
                          (three, 7.1525573730e-07),
                          ],
                         ids=["one", "two", "three"])
...

這給了你:

=============================================== short test summary info ===============================================
PASSED test.py::test_method[one]
PASSED test.py::test_method[two]
PASSED test.py::test_method[three]
================================================== 3 passed in 0.06s ==================================================

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM