Pythonスキルの習得

Python ユニットテスト 入門(pytest)

python ユニットテスト 入門 pytest

こんにちは、Zero-Cheeseです。

私は社会人になってから、独学でプログラミングを学習した者です。

独学で勉強していると、つい見落としがちなのが、コードの品質になります。

私は、ソフトウェア部署への異動面談で以下のやりとりをしました(笑)

面接官:「ソフトウェアの品質担保、つまり品質工学の技術はどれ位お持ちですか?」

私:「(品質工学・・・ 初めて聞いた・・・・ えべ・・。)あの、えと(汗)・・」

面談位なら、慌てて終わるだけで済みますが、ソフトウェア品質が担保できないと、色々な所に迷惑をかけたりして、大変です。(ホントに・・・)

本記事では、品質担保の1つであるソフトウェアテストの、導入方法から実行までをご紹介致します。

筆者

コードのユニット単位で、テストにより品質を保証した後に、次のコードを書く癖をつけると、心理的な安心感が全然違ってきます!

前提

この記事では、「pytest」を紹介します。

pythonには標準で使用できる「unittest」がありますが、「pytest」が上位互換のため、こちらを学ぶのがベターです。

unittestで作ったコードでも、pytestから実行できるよ!

pytestのインストール方法を紹介した後、PyCharm上からの実施方法、コマンドからの実施方法の順番で、ご紹介します。

インストール方法

pipでインストール可能です。

pip install pytest

テスト手順

テストされる側のコードを準備

まずは、ソフトウェアとして必要なコードを作ります。(テスト駆動を採用している場合は、先にテストから作ります。)

例えば下記のコードがあったとします。

(本記事では、IDEとして、PyCharmを使用した例をご紹介します。)

テストコードの準備

次にテストファイルを作ります。

名前は「test_〇〇.py」のようにtest_から初めるのがお約束です。

〇〇は任意名でOKですが、後で振り返って、何のテストをしているのか分かる名前にします。(ここでは、 test_add_functionにしました。)

テストコードの作成

まずは、クラスを使わない方法をご紹介します。

# ⬇テストされる関数の呼び出し (先程、自作したコード)
from add_function import add
 
def test_add(self):
   assert add(10, 5) == 15
  # ⬆ if文の条件式を書くような感じで書ける

次にクラスを使用した方法です。この方法を覚えておく方が、応用が効くと思います。

# ⬇テストされる関数の呼び出し
from add_function import add

class TestAdd(object):
    def test_add(self):
        assert add(10, 5) == 15
筆者

unitetestの場合、unittest.TestCaseを継承する必要がありますが、pytestの場合は不要です。

クラス名は「Test〇〇」がお約束です。
〇〇は任意名です。

メソッド名は、「test_△△」がお約束です。△△も何でもOKです。

テスト実行手順(PyCharm版)

PyCharm上での手順をご紹介します。(のちほど、コマンドからの実行例を紹介します。)

まずは、Edit Confiurationsをクリックします。(メニューバーからは、[Run] > [Edit Configurations])

MACの場合、下図の矢印になります。(windowsの場合、もう少し右にあります。)

次に、下記のダイアログが出現します。左上の+を押します。

一覧の中から、「pytest」を選択します。

次に、テストの「Target」と、作業場所「Working directory」を埋めればOKです。(下図の矢印部参照

記入後、右下の「OK」ボタンを押します。

そして下記ボタンを押して実行します。すると画面下部にテストがOKだった事が示されます。

参考までに、NGの場合は以下の画面が出現します。(IDE画面下の部分のみ表示)

テスト実行手順(コマンド版)

コマンドプロンプトから実行する場合は、以下の通りです。

# ファイル名を指定して実行
pytest ファイルパス
# 例)pytest test_add_function.py 

# フォルダを指定して実行
# フォルダに含まれるテストは全て実行されます。
pytest フォルダパス
# 例)pytest ./ 

実行すれば、下記のような結果が返ってきます。

その他、知っておくと便利な機能

テストの開始前、開始後に実行されるコードの書き方をご紹介します。

以下の順番で、ご紹介いたします。

  • 各テストメソッドの開始前、開始後に実行されるコードの紹介
  • テスト全体で開始前、開始後に1度だけ実行されるコードの紹介

前提として、下記コードのように、複数のテストメソッドを持つクラスがあったとします。

# ⬇テストする関数を呼び出し
from add_function import add


class TestCalculation(object):
    def test1(self):
        assert add(10, 5) == 15

    def test2(self):
        assert add(10, -1) == 9
各テストメソッドの開始前、開始後に実行されるコード

下記コードの、「setup_method」が開始前、「teardown_method」が開始後に実行されます。
下記コードの場合、test1とtest2の前後で実行されます。

class TestCalculation(object):
    def setup_method(self, method):
        print('各テスト実行前')

    def teardown_method(self, method):
        print('各テスト実行後')

    def test1(self):
        assert add(10, 5) == 15

    def test2(self):
        assert add(10, -1) == 9
テスト全体で開始前、開始後に1度だけ実行されるコードの紹介
「setup_class」が全体開始前、「teardown_class」が全体終了時に実行されます。
class TestCalculation(object):
    @classmethod
    def setup_class(cls):
        print('開始前に実行')

    @classmethod
    def teardown_class(cls):
        print('終了時に実行')

    def test1(self):
        assert add(10, 5) == 15

    def test2(self):
        assert add(10, -1) == 9

更に深い使用方法が必要な方へ

次回の記事では、更に深いpytestの使い方をご紹介します。

具体的には、conftest、fixture、カバレッジ、mock、またFlaskを使った際のDBテスト方法を記す予定です。

近日中に公開します。

公開しました。

python ユニットテスト まとめ pytest
Python ユニットテスト まとめ(pytest)Pythonのユニットテスト方法を網羅的にまとめました。よく使用するもの、ピックアップしてご紹介しました。...

雑談

私は初めてユニットテストを知った時に、どうして莫大な労力を使って、テストコードを書く必要があるのか、全然理解できていませんでした。

一回、痛い目に会って、テストの価値が分かりました(笑)

皆様は、私と同じ間違いを起こさない事を祈るばかりです。(まあ普通の会社ならば、どこまでテストするべきか、ルールがあるとは思いますが・・)

また、「どんなテストを書いたらいいんだろう?」と思ってる方もいるかと思います。

以前、テスト技法という事でご紹介させて頂きました。

もしご興味がありましら、参考にして頂ければと思います。

アイキャッチ
ソフトウェアテスト技法 入門ソフトウェアの品質担保の1つである「ソフトウェアテスト技法」の紹介です。ブラックボックステストを一通り網羅しています。...

最後まで読んで頂き、ありがとうございました。