pytest + seleniumでfixtureを使って共通処理をまとめる
以前の記事でsetup_method/teardown_methodを使って共通処理をまとめました。今回はそれと同様のことをpytestのfixtureというものを使って実現したいと思います。
setup_method/teardown_method
を使った方法は以下の記事をご覧ください。
環境
手順
前回での記事の内容の通り、setup_method/teardown_method
に記載した処理が共通処理になります。
今回はタイトルにもある通りpytestのFixtureという機能を使っていきます。fixtureとは何か:
pytest fixtures offer dramatic improvements over the classic xUnit style of setup/teardown functions:
https://docs.pytest.org/en/latest/fixture.html#pytest-fixtures-explicit-modular-scalable
pytestの公式ページにある文言を転記させてもらいましたが、今までのxUnitスタイルであるsetup/teardonw
を劇的に改善すると書いてあります。
劇的にと言い切るのがすごいですね 笑。それでは実際のコードを見ながらfixtureを紐解いて行きましょう。
conftest.py
という見慣れないファイルがあるの気がつくと思いますが、今回は2つのファイルに分かれています。conftest.py
もpytestの仕組みのひとつになります。conftest.py
はこのpytest fixtureとの相性が良く、今回はこの2つの仕組みを使って、共通処理をまとめていきます。
conftest.py って何?
pytestはpluginを読み込む過程の中で、conftest.py
をtest fileがあるディレクトリ(カレント及び親)から読み込みます。その過程で読み込まれたconftest.py
に記載されている処理は、共通処理として、テストが実行される処理の中で呼び出されます。
https://docs.pytest.org/en/latest/fixture.html#conftest-py-sharing-fixture-functions
fixture って何?
fixtureを使った機能はいくつかあります。その中で今回使うのは2つの機能:
@pytest.fixture
のアノテーションを関数に付与することで、その関数はfixture objectとして扱われ、Test function (テストケース) の引数として扱うことができます。
今回のサンプルのコードであるconftest.py
の中で、google
という関数を@pytest.fixture
のアノテーションが付与されているのがわかると思います。さらに、test_google.py
の中の各テストケースの引数として先程のgoogle
という関数を与えています。
更にその引数のgoogle
を使ってそれぞれのテストケースでfind_element_by_**
を呼んでいます。さて、ここで疑問になるのがgoogle
の実体。google
は一体何者なのでしょうか。答えは次に紹介するfixtureの機能にあります。
@pytest.fixture
のついた関数google
の中でもうひとつ見慣れないコードがあります。それはyield
。
このyield
を使うことで関数内の処理を一旦一時停止して、それ以降の処理を一旦日出し元に返すことができます。pytestのケースでその呼び出し元は実際のテストケースになります(今回の例ではtest_logo
とtest_input_field
)。この一時停止の機能により、yield
の前後にsetup_method/teardown_method
相当の処理を書くことで、setup_method/teardown_method
と同等の機能を実現することができます。
さらにyield
を使うと、通常のreturn
と同様に、呼び出し元に値を返すこともできます。なので、今回は初期化済みのWebdriverであるdriver
を返却しています。これにより、呼び出し元であるtest_logo
などのテストでそのままdriver
を介した処理を継続することができるのです。
まとめ
今回はpytestのfixtureを使ってテストの前処理と後処理をひとつの実装にまとめてみました。
上述の通りpytestのfixtureは強力で、上記で説明した機能以外にも、fixtureのscopeをfunction
以外にもmodule
やsession
に変更したり、パラメータを渡したりと様々な機能を有しています。興味がある方は以下のリンクから詳細を覗いてみてください。
pytest fixtures: explicit, modular, scalable — pytest documentation