Python pytestでconftestを使う

Python学習【365日チャレンジ!】181日目のマスターU(@Udemy11)です。

気づけば目標としていた180日(6ヶ月)を過ぎていました。

1年間365日の継続学習が最終目標なので、181日目なので、まだ折り返していませんが、これだけの期間を毎日継続できたのは、あとにも先にも記憶にございません!

最近の学習は、Pythonでプログラムを書く上での付随的な内容が多いので、基本的なPythonのコードの書き方も復習しつつレクチャーを進めていかないと、忘れてしまうことが増えてきそうです。

次の目標は、300日(10ヶ月)に設定してPython学習を継続したいと思います。

それでは、今日もPython学習をはじめましょう。

昨日の復習

昨日は、pytestでテストをスキップする方法を学習しました。

unittestと同じように、普通にテストをスキップする方法と条件をつけてスキップする方法がありました。

コードの書き方もほぼunittestのときと同じで、少し記述が変わる程度で、非常に簡単にテストのスキップをすることができました。

pytestによるテストのスキップの詳細については、昨日の記事を参考にしてください。

今日は、pytestを実行する際に、オプションを渡して実行することができるconftestを学習します。

conftestの利用シーン

オプションを渡すといっても、私のようにいまいちよくわからない方もいるかと思うで、具体的にどのようなことをするのか考えてみましょう。

ターミナルでPythonを実行するときは、python ファイル名とコマンド入力しますが、この後に--をつけたオプションと一緒に実行することで追加の処理を行うことができます。

たとえばターミナルの操作に関連して、subprocessを使ってコマンドを渡す場合、Macならディレクトリを表示するコマンドはlsでWindowsならdirなので受け取る値によって、引き渡す値を変更してテストを実行することができます。

os_name = "mac"
if os_name == 'mac':
   print('ls')
elif os_name == 'windows':
   print('dir')

このようなコードをtest_calculation.pyに加えていきます。

calculation.py

今回のテストもテストするメインのファイルはcalculation.pyです。

class Cal(object):
   def add_and_double(self, x, y):
       if type(x) is not int or type(y) is not int:
           raise ValueError
       result = x + y
       result *= 2
       return result

conftest.py

これまでのテストで利用してきたtest_calculation.pyも使用しますが、まずconftest.pyを作成します。

pytestでテストファイル(test_calculation.pyを実行する場合、同じディレクトリにconftest.pyがあれば、先にconftest.pyを自動的に読み込みます。

その読み込まれるconftest.pyのコードを書いてみます。

def pytest_addoption(parser):
   parser.addoption('--os-name', default='linux', help='os name')

このファイル(conftest.pytest_calculation.pyと同じディレクトリに置けば、pytestを実行するとコマンドから--os-nameをオプションで受け取れるようになります。

コマンドにオプションが入力されていなければ、--os-nameにはデフォルトでlinuxが代入されます。

この状態で、ターミナルからpytestコマンドでtest_calculation.py--helpオプションを加えて実行すると、カスタムオプションに--os-opitionos nameが付け加えられているのが確認できます。

Python pytestでconftestを使う

test_calculation.py

次にテストを実行するtest_calculation.pyを書いていきましょう。

import calculation

class TestCal(object):
    def test_add_and_double(self, request):
        os_name = request.config.getoption('--os-name')
        print(os_name)
        if os_name == 'mac':
            print('ls')
        elif os_name == 'windows':
            print('dir')
        cal = calculation.Cal()
        assert cal.add_and_double(1, 3) == 8

今回のtest_calculation.pyは、1つだけのテストでコードを書いています。

4行目でテストの関数を定義するときに、引数にrequestを加えて、5行目で、config.getoptionによって、指定した引数の値をos_nameで受け取ります。

6行目でわかりやすいようにprint出力していますが、本来はこの出力は不要です。

7行目から10行目で、最初に解説したように、MacとWindowsで出力するコマンドを分けています。

その後、テストを実行するコードですが、今回は出番なしみたいなものですね。

実行結果

Pycharmからtest_calculation.pyを実行すると、デフォルトでlinuxが代入されるため、7行目から10行目では、何も出力されずにテストが実行されます。

Python pytestでconftestを使う

次に、ターミナルからpytest test_calculation.py --os-name=mac -sを実行すると、次のように表示されます。

Python pytestでconftestを使う

ちなみに-sは、print出力を表示するための
オプションです。

次にmacではなく、windowsを入れてpytest test_calculation.py --os-name=windows -sで実行してみます

Python pytestでconftestを使う

windowsdirが表示されているのがわかるかと思います。

このように、オプションで受け取った値の条件によって、引き渡す値を変えたテストをすることができます。

テストじゃなくても

今回は、値を受けて、その値によってデータを返すというテストをしました。

プロではない私からすると、運用するにあたって、ほんとにいろいろなテストが必要なんだなとプログラマーの大変さが徐々にわかるような内容でした。

果たしてテストってどこまでしなければいけないんだろうな?という漠然とした疑問がありますが、酒井さんの講座には、この先、この問いかけに関するレクチャーもあるので、後ほど紹介しようと思います。

ちなみに、私が今Pythonを学習している講座はこちらです。

Udemy講師 酒井さん プログラミング Python

基本から応用までかなり濃い内容なので、セールなどで安くなったときにぜひお試しください。

それでは、明日もGood Python!