一般的にPythonでプロジェクトを作る場合、以下のようにすることが多いと思います。
- srcフォルダ配下に実際に使うソースコード
- testsフォルダ配下にテストケース
+ プロジェクトルート
|
+---src
| +---ここにソースファイル
| +---ここにソースファイル
| +---ここにソースファイル
| +---ここにソースフォルダ
| \---ここにソースファイル
+---tests
| +---test_ここにテストケース.py
| +---test_ここにテストケース.py
| \---test_ここにテストケース.py
\ (必要に応じて)起動スクリプトなど
で、通常はプロジェクトルートフォルダをカレントディレクトリとし、python .\src\main.py
などとしてプログラムを起動する というのが、Python的に推奨されたプログラムの実行方法 だと思っています。
さて、そのような場合、testsフォルダ配下のテストケースとsrcフォルダ配下の実ファイルにて、参照パスが異なってくるため、srcフォルダ内でフォルダを分けたりすると、参照パスがずれてきてテストケースでModuleNotFoundErrorが頻発します。
そのような場合、とりあえずの対処として、ModuleNotFoundErrorが発生したらテスト環境とみなし、srcフォルダからのフルパスを指定することでなんとか対処していたのですが…
import unittest
try:
import プロジェクト内の別モジュール
except ModuleNotFoundError:
import src.プロジェクト内の別モジュール
…
最近これでもModuleNotFoundErrorがたまに出てくるようになってしまい、どうしたものかと思っていました。
解決策
テストケースのファイル先頭で、srcフォルダ配下にも参照パスを追加して、srcフォルダ配下にファイルが置かれているのと同じ状態にしました。
import unittest
from pathlib import Path
import sys
sys.path.append(str(Path(__file__).parent.parent))
sys.path.append(str(Path(__file__).parent.parent / "src"))
import src.テスト対象のモジュール
class Test_TEST(unittest.TestCase):
pass
このようにすると、Visual Studio Code上でも、テストケース上でも、もちろん実際に実行するプログラム上でもModuleNotFoundErrorには悩まされなくなります。
また、テスト対象の(src配下の)ファイルでも、ModuleNotFoundErrorをキャッチして処理を分けるなんていう面倒くさいこともしなくて良くなりました。
正直この方法が正しい方法なのかどうかわかりませんが、ひとまず問題はなくなった ということで。