やりたいこと
- pytest を使って unittest を実行したい
- プロダクトコードとテストコードはディレクトリで分けたい
- まさに参考リンクのイメージ
- 実行時は
python -m pytest
とかで勝手に test_XXX を discover して実行してほしい
上手くいかないこと
- 参考リンクの通りで、class_module.py の
imoprt class_BaseModule
でModuleNotFoundError
になる- テスト対象スクリプトから同ディレクトリ内の別モジュールを素で
import
していて、これが見つからない
- テスト対象スクリプトから同ディレクトリ内の別モジュールを素で
- 解決法にある
sys.path.append()
って全テストコードの先頭に書くの?しかもモジュールコードまでの相対パスは自前で書かないといけないってそれマジ?ダサくない?(回答者の方ががダサいわけではない) - 参考リンクの参考リンクにある 以下と心境は同じ
I know I could modify PYTHONPATH and other search path related tricks, but I can't believe that's the simplest way
解らしきもの
pytest のドキュメントに記述があった。
- venv で環境を切って自身の開発モジュールを
pip install -e .
でインストールする - そのためにプロジェクトルートに簡単な setup.py を置いておく
- モジュール内のコードはパッケージ(下の例では
hoge
)からの import パスを書く。つまり、b.py 中で モジュールa
を使う場合、import a
とするのではなく、from hoge import a
とする。
sample_project
┣ hoge
┃ ┣ __init__.py
┃ ┣ a.py
┃ ┗ b.py
┣ test
┃ ┣ __init__.py
┃ ┗ test_b.py
┗ setup.py
a.py
# coding: utf-8
def a(src):
return 'aaa' + src
b.py
# coding: utf-8
from hoge import a
def b(src):
return a.a(src + 'bbb')
if __name__ == '__main__':
print(b('hoge'))
このとき、hoge ディレクトリ下で python b.py
を実行すると ModuleNotFoundError: No module named 'hoge'
になる。
これを回避するにはプロジェクトルートから python -m hoge.b
と実行するとよい。
まとめ
- モジュール内で同ディレクトリ内の別モジュールを使う際も、
from package import module
とすべきで、素でimport
と書くのがむしろダサい(?) - 素で
import
書くような(ローカルで完結する規模の)プロジェクトならテストコードをわざわざ別ディレクトリ構成にしなくてもええやん? - モジュールとしてきちんとディレクトリ分けてテストを管理したいなら、pytestにあるようなプラクティスに従おうね
- でもまあそういうテストの準備が簡単にできるようなスケルトン生成ツールみたいなのはあってもいいんじゃないかと思た(探せばありそう)
おわり