プログラミングと株式投資のブログ

プログラミングで株式投資に役立つ何かをやってます

pytestのメモ

インストール

pip install pytest

 

実行

プロジェクトルートで

pytest

を実行する。これでテストコードを自動検索しテストを実行してくれる。デフォルトではtest_*.pyや*_test.pyを再帰的に検索する。試験対象となるメソッドはtest*や*testとなる名称のメソッド。

実行対象の発見ルールはここが詳しい。
 

単体テストの書き方

基本

assertで想定された状態か確認する

import pytest
def test_code() :
    #値が想定された値か
    assert a == 100

    #pythonの組み込み関数 getattrでオブジェクトの要素を取得する
    assert getattr(dao, '_conn') is None

    #pythonの組み込み関数 isinstanceでオブジェクトの型を確認する
    assert isinstance(dao._conn, sqlite3.Connection)

 
例外の発生を確認する

import pytest
def test_code() :
    with pytest.raises(Exception) :
        exception_throw_method()

 
一時ディレクトリを使用する

import pytest
#tmp_path fixture使用することで一時ディレクトリを使用できる
def test_code(tmp_path) :
    dao.connection(str(tmp_path / 'test.db'))

 

独自のfixtureを実装する

テストコード実行時であってもcloseなどの開放処理は確実に実行したい。そのために独自にfixtureを実装することが推奨される。

import pytest
@pytest.fixture
def default_dao(tmp_path):
    dao = EdinetDao(str(tmp_path / 'test.db'))
    dao.connect()
    dao.ensure_tables()

    #test_codeメソッドにdaoが渡される
    yield dao

    #ティアダウン(後片付け処理)
    #この処理はtest_codeメソッド実行後にpytestによって必ず実行される
    try:
        dao.close()
    except :
        pass

def test_code(default_dao) :

    #default_daoを使ったテストコード

Mockによりメソッドの動作を模擬する

import pytest

def test_code(default_dao) :
    from unittest.mock import Mock

    #default_dao.connectionの失敗を模擬する
    #ここではExceptionを発生させる
    #default_dao.connectionメソッドはインスタンスのプロパティ_connの
    #connectionメソッドを呼び出すため_connがconnectionメソッドを呼び出したときに
    #Exceptionを発生するように処理を置き換える
    bad_conn = Mock()

    #例外を発生させるときはside_effectを設定する
    bad_conn.connection.side_effect = Exception()
    #返り値を設定するにはreturn_valueを設定する

    #別関数は本物の関数のメソッドを呼び出したいときは
    #side_effectを設定する
    #real_conn = default_dao
    #bad_conn.cursor.side_effect = real_conn.cursor

    with pytest.raises(Exception) :
        default_dao.connection()