LoginSignup
19
14

More than 5 years have passed since last update.

pytest でモジュールコードとテストコードをディレクトリで分離して unittest を実行するには?

Posted at

やりたいこと

  • pytest を使って unittest を実行したい
  • プロダクトコードとテストコードはディレクトリで分けたい
  • 実行時は python -m pytest とかで勝手に test_XXX を discover して実行してほしい

上手くいかないこと

  • 参考リンクの通りで、class_module.py の imoprt class_BaseModuleModuleNotFoundError になる
    • テスト対象スクリプトから同ディレクトリ内の別モジュールを素で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にあるようなプラクティスに従おうね
  • でもまあそういうテストの準備が簡単にできるようなスケルトン生成ツールみたいなのはあってもいいんじゃないかと思た(探せばありそう)

おわり

19
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
14