Test class instance is not recreated when retrying tests
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 42/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 停滞
- 技術スタック
- python
- 領域
- testing-qa, tooling
調査の方向性
まず、提供された flaky test を pytest 7 と pytest 6.5.2 で実行し、次に issue に示されている flaky decorator と pytest_runtest_setup hook 周辺の retry path を調査します。完了条件は、retry が新しいテストクラスのインスタンスを使用し、fixture の setup と teardown を壊さず、インスタンスの分離をカバーする regression test があることです。
索引モデルが issue の本文から書いたものです。
説明
Since upgrading to pytest>=7.0.0, the self parameter between test runs remain the same when retrying a single test function within a test class. When using pytest==6.5.2, it is working as expected, the self parameter refers to a new instance every time the test is run.
To reproduce the issue, you can use the following code:
import pytest
from flaky import flaky
class TestExample:
@property
def counter(self):
self.__dict__.setdefault('_counter', 0)
self._counter += 1
return self._counter
@pytest.fixture(autouse=True)
def some_fixture(self):
print('SETUP', self.counter)
yield
print('TEARDOWN', self.counter)
@flaky(max_runs=5)
def test_something(self, param=[]):
print('TEST', self.counter)
param.append(0)
assert len(param) > 2
def test_other(self):
print('OTHER', self.counter)
Running these tests output the following, showing that the same instance is used for self when retrying the test:
SETUP 1
TEST 2
TEARDOWN 3
SETUP 4
TEST 5
TEARDOWN 6
SETUP 7
TEST 8
.TEARDOWN 9
SETUP 1
OTHER 2
.TEARDOWN 3
I think this should be considered as a bug, see for example the commit message of https://github.com/pytest-dev/pytest/commit/0dc036035107b213c9b73bf965cbd7356111b85a which states This is definitely broken since it breaks test isolation. for a similar case.
I could work around this issue in a really ugly and fragile way using a pytest hook like this, but I think this should be fixed properly within flaky:
import pytest
import weakref
from typing import Any, Generator
last_weak_obj_key = pytest.StashKey[weakref.ref[Any]]()
last_weak_instance_key = pytest.StashKey[weakref.ref[Any]]()
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_setup(item: Any) -> Generator[None, Any, None]:
last_weak_obj = item.stash.get(last_weak_obj_key, lambda: None)
last_weak_instance = item.stash.get(last_weak_instance_key, lambda: None)
assert item.obj is not None
if item.obj is last_weak_obj() or (
item.instance is not None and item.instance is last_weak_instance()
):
# Deleting these two internal attributes trigger new instance creation when accessing item.obj or item.instance the next time
del item._obj
del item._instance
assert item.obj is not None and item.obj is not last_weak_obj()
item.stash[last_weak_obj_key] = weakref.ref(item.obj)
assert item.instance is None or item.instance is not last_weak_instance()
item.stash[last_weak_instance_key] = weakref.ref(item.instance)
yield
As pytest-rerunfailures is also affected, I've opened this issue there as well: https://github.com/pytest-dev/pytest-rerunfailures/issues/268
- 主要言語
- Python
- スター
- 399
- フォーク
- 58
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
box/flaky のほかの issue
-
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
-
難易度 3/5 1〜2日 初心者へのやさしさ 38/100
-
難易度 3/5 1〜2日 初心者へのやさしさ 48/100
-
難易度 5/5 1週間以上 初心者へのやさしさ 15/100
-
難易度 4/5 3〜5日 初心者へのやさしさ 25/100
似ている issue
-
ChatBedrockConverse changes the keys of JSON tool results to camelCase (`order_id` becomes `orderId`)対応中かも @geyazheng が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
langchain-ai/langchain-aws#1469 ·
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信
-
b4b usability
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
fix(schedule): align list_tasks since cursor filter boundary from strict > to >=対応中かも @bfs2021 が今日担当しました。 オープンagent-ready bug p2 schedule
難易度 2/5 1〜3時間 初心者へのやさしさ 83/100
allenporter/supernote#540 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
frazane/scoringrules#164 ·
メンテナーはふだん 1 日以内に返信