簡體   English   中英

如果夾具設置或拆卸失敗,有沒有辦法跳過 pytest?

[英]Is there a way to skip pytest if fixture setup or teardown fails?

如果夾具的任何部分拋出異常,有沒有辦法跳過測試? 我正在使用第三方夾具,該夾具在拆卸過程中會隨機出錯,因此我試圖包裝我的測試,以便在拋出隨機錯誤時(注意:測試沒有失敗,夾具出錯了) , pytest只是跳過測試。

這是一個最小的可重現示例:

import functools
import numpy as np
import pytest


def handle_fixture_errors(f):
    """decorator for wrapping test function in try/catch"""
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        try:
            print('about to run my test')
            return f(*args, **kwargs)
            print('never reached')
        except Exception as e:
            msg = 'Ignoring fixture exception ' + str(e)
            pytest.skip(msg)

    return wrapper

@pytest.fixture()
def failing_fixture(request):
    """fixture fails on teardown"""
    x = np.linspace(10, 20, 100)
    y = np.random.normal(size=(1000, 5))
    def teardown():
        print('fixture teardown is failing')
        z = x.T.dot(y)
    request.addfinalizer(teardown)
    return x


@handle_fixture_errors
def test_matmul(failing_fixture):
    """original test function"""
    print('hey this is my test')

    k = failing_fixture
    assert len(k) == 100

問題是測試本身沒有拋出異常,它是拋出異常的夾具,所以try/catch沒有捕獲測試的異常並阻止“.E”產生測試摘要。 我的測試 output 仍然看起來像這樣:

========================================================= ERRORS =========================================================
____________________________________________ ERROR at teardown of test_matmul ____________________________________________

    def teardown():
        print('fixture teardown is failing')
>       z = x.T.dot(y)
E       ValueError: shapes (100,) and (1000,5) not aligned: 100 (dim 0) != 1000 (dim 0)

test_fake.py:25: ValueError
-------------------------------------------------- Captured stdout call --------------------------------------------------
about to run my test
hey this is my test
------------------------------------------------ Captured stdout teardown ------------------------------------------------
fixture teardown is failing
================================================ short test summary info =================================================
ERROR test_fake.py::test_matmul - ValueError: shapes (100,) and (1000,5) not aligned: 100 (dim 0) != 1000 (dim 0)
=============================================== 1 passed, 1 error in 0.18s ===============================================

我不想跳過設置或拆除夾具,我只想讓測試被完全“跳過”(或至少,靜音或pass )。 謝謝你的幫助!

我認為跳過這樣的測試是不合理的。 要么你想要,要么你不想要!

如果你有間歇性測試(或者在這種情況下是固定裝置),考慮重新運行它們,也許在短暫的延遲或一些檢查之后(網絡流量太高?在非高峰時間再試一次)

pytest 為此建議了一些看起來高質量的插件,並且可以在運行之間添加延遲等
https://docs.pytest.org/en/stable/flaky.html#plugins

如果您確切知道哪里會失敗,請考慮在您的代碼放棄或將控制權交還給 pytest 之前自行重試幾次,方法是在某個循環中設計您的邏輯

for _ in range(10):  # attempt call 10 times
    time.sleep(10)  # yuck
    try:
        foo = flakey_call()
    except Exception:
        continue  # failed: try again, consider different waits
    if hasattr(foo, "bar"):
        break  # successfully got a valid foo
else:  # did not find and break
    raise Exception("the foo had no bar!")

也可以選擇模擬第 3 方夾具(我會提醒您不要這樣做,因為它可能導致夾具永遠無法工作),或每次運行

設計一些邏輯來獲得第 3 方邏輯的響應,可能會在夾具中重新運行它,直到它執行您想要的操作。

然后要么

  • 將其序列化為對您有用的形式並將其保存以供將來運行(例如,如果它是一些數據收集,則為鑲木地板)
  • 腌制 object (我只會在有很多調用的情況下單次運行,但現在只需要成功)

暫無
暫無

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

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