大規模なプロジェクトでは、ある時点で、プロジェクトに対してすでに多くのテストが行われ、並行して、独自の高レベルのフレームワークが開発されている状況が発生します。この場合のフレームワークは、テストオブジェクトの機能と、プロジェクトで使用されるさまざまなツールの機能のラッパーとして機能します。さらに、すべてのフォルダはフィクスチャで満たされ、その多くは1つのテストファイルでのみ使用されます。
この素晴らしい瞬間に、いくつかの問題が発生します。そのうちの1つについてはすでに書いていますが、これは、たとえばファイルからの便利なパラメーター化の実装です。この記事で最も不幸な次の問題について説明します。
「キャプテン、たくさんの備品があり、グローバルが登場します。」
テストディレクトリにフィクスチャをオーバーロードすることは、py.testに含まれている概念を使用することの論理的な結果ですが、このアプローチが許容範囲を超える場合があります。さらに、特定のケースでテストが取得する必要のある情報を決定するように設計されたテストの構造や、環境の準備段階でさらにテストに合格する可能性を最初に確認したいという要望をよく観察できます。
これらの構成が何らかのsetupフィクスチャから渡され、テスト全体に渡る状況での最大の誤解は、global変数を使用することです。私も同様の困難なケースに直面しており、この考えは最初に頭に浮かぶものの1つです。
この時点で、フィクスチャの概念はこのコードのクリーンさの汚染を回避するだけでなく、追加レベルの抽象化と多くの参照を提供することを言及する価値があります。最後の手段として、フィクスチャの結果を開梱するというひどい習慣を得ることができますが、この場合、ログを台無しにします。セットアップ、実行、ティアダウンに分割されておらず、結果を解凍するときや複数のショートカットを作成するときに、コードがさらに複雑になります。
いくつかの例を見て、最悪の場合から始めましょう。
「フィクスチャとグローバル」
import pytest
@pytest.fixture(autouse=True)
def setup(create_human, goto_room, goto_default_position, choose_window, get_current_view):
global human
global window
#
desired_room = 1 # ,
human = create_human("John", "Doe") #
# - ,
assert goto_room(human, desired_room), "{} {}".format(human.full_name, desired_room)
#
window = choose_window(desired_room)
view = get_current_view(window)
assert view, " {} ".format (window)
yield
# Teardown
goto_default_position(human)
@pytest.mark.parametrize(
"city, expected_result",
[
("New York", False),
("Berlin", False),
("Unknown", True)
]
)
def test_city_in_window(city, expected_result):
""" ."""
window_view = human.look_into(window)
recognized_city = human.recognize_city(window_view)
assert (recognized_city == city) == expected_result, " "
結果として:
- 初期チェックがあります
- 不運があります
global
" "
import pytest
@pytest.fixture
def setup(create_human, goto_room, goto_default_position, choose_window, get_current_view):
#
desired_room = 1 # ,
human = create_human("John", "Doe") #
# - ,
assert goto_room(human, desired_room), "{} {}".format(human.full_name, desired_room)
#
window = choose_window(desired_room)
view = get_current_view(window)
assert view, " {} ".format (window)
yield { "human": human, "window": window}
# Teardown
goto_default_position(human)
@pytest.mark.parametrize(
"city, expected_result",
[
("New York", False),
("Berlin", False),
("Unknown", True)
]
)
def test_city_in_window(setup, city, expected_result):
""" ."""
data = setup
window_view = data["human"].look_into(data["window"])
recognized_city = data["human"].recognize_city(window_view)
assert (recognized_city == city) == expected_result, " "
:
-
setup - , ,
, 400+ , .
, 8 setup : , ?
— . py.test, .
:
import pytest
class TestWindowView:
@pytest.fixture
def setup(self, create_human, goto_room, goto_default_position, choose_window, get_current_view):
#
desired_room = 1 # ,
self.human = create_human("John", "Doe") #
# - ,
assert goto_room(self.human, desired_room), "{} {}".format(human.full_name, desired_room)
#
self.window = choose_window(desired_room)
view = get_current_view(self.window)
assert view, " {} ".format (self.window)
yield
# Teardown
goto_default_position(self.human)
@pytest.mark.parametrize(
"city, expected_result",
[
("New York", False),
("Berlin", False),
("Unknown", True)
]
)
def test_city_in_window(self, setup, city, expected_result):
""" ."""
window_view = self.human.look_into(self.window)
recognized_city = self.human.recognize_city(window_view)
assert (recognized_city == city) == expected_result, " "
:
-
global
, .
, . , .
Android/iOS Appium IOT/Embedded .