Python の勉強 スロットゲーム編 〜その17:テスト(pytest)〜

プログラミング

pytest はサードパーティのライブラリです。そのため先ずは以下のコマンドでインストールする必要があります。

pip install pytest

なぜ unittest があるのに pytest をわざわざ使うのか…というのはご想像の通り、pytest の方が優れている面があるからです。実際のところ……私はそこまで使いこなせていないので、「こんなに凄いんだ!」という意見はまだありません。そのため簡単に使い方を紹介するに留めます。今後、「これだー!」という間隔が降りてきたら別途、記事に起こそうと思います。

pytest を使ってみる

unittest と異なるのは

  • pytest をインポートする(当然)
  • テストクラス(TestXxx)を定義する必要がない
  • テスト対象をパッケージから指定する
  • assertXxx(...) の代わりに、assert a == b の様な表記をする
  • テスト実行時は「pytest 対象ファイル」というコマンドを使用する
from io import StringIO
import unittest.mock            # print()、input() をテストするために必要

import pytest

from my_slotgame import game017 # パッケージ(__ini__.py があるフォルダ)から指定する


def test_is_bets_valid():             # test_xxx_xxxx という名前にする決まり
    assert game017.is_bets_valid('100', 100) == (True, None)
    assert game017.is_bets_valid('200', 100) == (False, '掛けコイン数は半角数字で入力して下さい。')
    assert game017.is_bets_valid('0', 100) == (False, '掛けコイン数は 1 枚以上を指定して下さい。')
    assert game017.is_bets_valid('101', 100) == (False, '掛けコイン数は所持コイン数以下を指定して下さい。')
    with pytest.raises(TypeError):
        game017.is_bets_valid('100', 'abc')

@unittest.mock.patch('sys.stdout', new_callable=StringIO)             # print() の結果をテストする準備
def test_show_start_message(mock_stdout):
    game017.show_start_message()
    assert mock_stdout.getvalue() == '--------------\nスロットゲーム\n--------------\n'

@unittest.mock.patch('sys.stdout', new_callable=StringIO)             # print() の結果をテストする準備
def test_ask_player_name(mock_stdout):
    with unittest.mock.patch('builtins.input', return_value="king"):  # input() を 'king' を返却するものに置き換え
        assert game017.ask_player_name() == 'king'
        assert mock_stdout.getvalue() == 'こんにちは king さん\n'

テストを実行する際は、以下で実行して下さい。

pytest my_slotgame/test_game017_2.py

テスト用のファイルを別フォルダに分離してみる

一般的には、実際のプログラムと、テスト用のプログラムは別のフォルダで管理します。テスト用のフォルダは「tests」フォルダを作成して、その中で、実際のプログラウト同じフォルダ構成を作成します。具体的には以下の構成になります。

├── my_slotgame
│   ├── __init__.py
│   └── game017.py
└── tests
    ├── __ini__.py
    └── my_slotgame
        ├── __ini__.py
        └── test_game017.py

ただ、ファイルの置き場所を変更すると、対象のファイルが見つからなくなってしまうので以下を追加します。

import os, sys
sys.path.append(os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../../"))

テストの実行は同じ様に pytest を使用してファイルを指定します。

pytest tests/my_slotgame/test_game017_2.py

コメント

タイトルとURLをコピーしました