お試し用プロジェクト
下記のような構成のプロジェクトを作った。
data.pyでDataクラスを定義し、calc.pyでDataクラスを引数に渡して計算する関数がある。という構成である。
+---pyapp
calc.py
data.py
__init__.py
__main__.py
data.py
from typing import Self
class Data:
def __init__(self, value: float) -> None:
self.value = value
def add(self, other: Self):
val = self.value + other.value
return self.__class__(val)
calc.py
from data import Data
def func(d1: Data, d2: Data) -> Data:
return d1.add(d2)
pytest準備
まずpytestをインストールする。
$ pipenv install pytest
testsフォルダを作成し、test_calc.pyを作る。
+---pyapp
| calc.py
| data.py
| __init__.py
| __main__.py
|
\---tests
test_calc.py
__init__.py
from pyapp.data import Data
from pyapp.calc import func
def test_calc1():
d1 = Data(1)
d2 = Data(2)
d3 = func(d1, d2)
assert d3.value == 3
VSコード上のTesting(フラスコのアイコン)をクリックすると図のようなwindowが表示されるので、Configure Python Test
をクリックする。
pytestを選択し、testsフォルダを選択すれば準備環境。
pytest実行
三角形のアイコンをクリックすれば実行できる。今回はエラー詳細も出したいので虫アイコンの方を押して、Debug Testを実行する。
分析
data.pyをこのようにDataクラスを読み込んで型アノテーションしないように書き換えると動く。
def func(d1, d2):
return d1.add(d2)
要するに、
- test_calc.pyからpyapp.calcの読み込みはできている。
- pyapp.calcを読み込む際に、その先のdataを読み込めていない。
ことがわかり、pathの問題であることがわかる。
解決方法(pathの設定)
二つやり方がある。
- conftest.pyで指定する
- .envファイルを作る
1. conftest.pyで指定する。
conftest.pyをtests内に配置すると、そのディレクトリ内のテスト時に自動的に読み込まれる。
もともとはフィクスチャというテストの前後処理の仕組みの共通化するためにもの。
フィクスチャはテストの実行前後で行いたい前処理・後処理を記述するために使用する関数のことです。各テストで同じ前処理・後処理を行う必要がある場合に暗黙的にそれが実行できるようになります。
複数のファイルをまたいで共通のフィクスチャを使用したいこともあると思います。そのような時はフィクスチャを conftest.py というファイルに定義しましょう。conftest.py 内のフィクスチャは pytest によって自動的にインポートされ、conftest.py があるディレクトリ配下で暗黙的に参照できるようになります。
今回はtestsフォルダ直下にこのようなconftest.pyを作るとテストが動きます。
import sys
import os
sys.path.append(os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + "/../pyapp"))
2. .envファイルを作る
プロジェクト直下に.envファイルを作り、下記のように書きます。
PYTHONPATH=./pyapp
そしてVSCodeの設定で作った.envを指定すると、実行時に.envを参照してpyappを追加してくれます。
参考