環境構築
# Pythonのバージョンを確認
python --version
> Python 3.7.3
# pytestのインストール
> pip install pytest
# pytest-mockのインストール
> pip install pytest-mock
ファイル構成
.
├── src
│ └── script.py
└── tests
├── __init__.py
└── test_script.py
テスト対象のコード
script.py
import os
# Method being tested
def delete_file(file_path):
try:
if not os.path.isfile(file_path):
return 'File does not exist'
os.remove(file_path)
return 'File deleted successfully'
except:
return 'An error has occurred'
テストコード(retrun_value
で戻り値を固定にする)
from src.script import delete_file
import pytest
def test_file_not_exist(mocker):
# os.path.isfile をモック化する(常にFalse)
mocker.patch('os.path.isfile', return_value=False)
# テスト対象を実行する
message = delete_file('test_file_path')
# 戻り値のメッセージを検証
assert message == 'File does not exist'
テストコード(side_effect
で任意の処理に差し替える)
from src.script import delete_file
import pytest
def test_file_not_exist(mocker):
# os.path.isfile をモック化(isfile_mock_funcが呼ばれる)
def isfile_mock_func(file_path):
return False
mocker.patch('os.path.isfile', side_effect=isfile_mock_func)
# テスト対象の実行
message = delete_file('test_file_path')
# 戻り値のメッセージを検証
assert message == 'File does not exist'
テストコード(例外を強制的に送出する)
from src.script import delete_file
import pytest
def test_file_not_exist(mocker):
# 例外を送出するモック
mocker.patch('os.path.isfile', side_effect=Exception)
# テスト対象を実行する
message = delete_file('test_file_path')
# 戻り値のメッセージを検証
assert message == 'File does not exist'
テストコード(モック化した処理に対する操作内容を検証する)
mocker.patch でモック化したモックオブジェクトを使うと、処理が何回呼ばれたか、どのような引数で呼ばれたかなどを検証することもできる。
例えば引数の内容と呼び出し回数をテストしたい場合以下のように書ける。
from src.script import delete_file
import pytest
def test_file_not_exist(mocker):
# モック化
isfile_mock = mocker.patch('os.path.isfile', return_value=True)
remove_mock = mocker.patch('os.remove')
# テスト対象の実行
message = delete_file('test_file_path')
# 戻り値のメッセージを検証
assert message == 'File deleted successfully'
# モック化した処理が1度だけ正しい引数で呼ばれたか検証
isfile_mock.assert_called_once_with('test_file_path')
remove_mock.assert_called_once_with('test_file_path')