Python サブモジュールのディレクトリ構造とunittestの話
プログラムとunittestを同じディレクトリに置くパタンのテスト。
パッケージ(hello_submodule)の同列にtestディレクトリを作って、unittestのファイルを置く構成が標準らしいが、パスの設定関係がとても面倒なので。
プログラムとunittestを同じディレクトリに置くパタンの場合、カレントディレクトリがhello_submoduleにあるものとしてfromなどを記述すればよさそう。
ディレクトリ構造
─hello_submodule │ program_main.py │ program_main_test.py │ ├─.vscode │ launch.json │ settings.json │ ├─sub_module_1 │ program_submod1.py │ program_submod1_test.py │ __init__.py │ └─sub_module_2 program_submod2.py program_submod2_test.py __init__.py
ソースコード
1. program_main.py
from sub_module_1 import program_submod1 from sub_module_2.program_submod2 import Class_Submod2 def main_func(): x = program_submod1.func1() y = Class_Submod2() z = y.func2() print("this function is program_main.main_func()") print(f"x={x}, y={y},z={z}") return 3 if __name__ == '__main__': main_func()
2. program_main_test.py
import unittest import program_main class Testprogram_main(unittest.TestCase): def test_main_func(self): self.assertEqual(program_main.main_func(), 3) if __name__ == '__main__': unittest.main()
3. program_submod1.py
def func1(): print("this function is sub_module_1.func1()") return (1)
4. program_submod1_test.py
import unittest from sub_module_1 import program_submod1 class Testprogram_submod1(unittest.TestCase): def test_func1(self): self.assertEqual(program_submod1.func1(), 1) if __name__ == '__main__': unittest.main()
5. program_submod2.py
class Class_Submod2: def __init__(self): self.v = 2 pass def func2(self): print("this function is sub_module_2.func2() in Class_Submod2") return (self.v)
6. program_submod2_test.py
import unittest from sub_module_2 import program_submod2 class Testprogram_submod2(unittest.TestCase): def test_func1(self): x=program_submod2.Class_Submod2() self.assertEqual(x.func2(), 2) if __name__ == '__main__': unittest.main()
7. __init__.py
空のファイル。
8. setting.json(vscodeの設定ファイル)
{ "python.testing.unittestArgs": [ "-v", "-s", ".", "-p", "*_test.py" ], "python.testing.pytestEnabled": false, "python.testing.nosetestsEnabled": false, "python.testing.unittestEnabled": true }
コマンドラインでのテスト実行例
(base) C:\dev\SampleCodes\hello_submodule>python -m unittest discover -p "*_test.py" this function is sub_module_1.func1() this function is sub_module_2.func2() in Class_Submod2 this function is program_main.main_func() x=1, y=<sub_module_2.program_submod2.Class_Submod2 object at 0x0000021BF07B07C8>,z=2 .this function is sub_module_1.func1() .this function is sub_module_2.func2() in Class_Submod2 . ---------------------------------------------------------------------- Ran 3 tests in 0.005s OK ||> *** パスの設定関係がとても面倒な理由 unittestファイル側から、テスト対象の関数が書いてある.pyファイルをimportしないといけないが、親ディレクトリをたどってimportする設定が手間なため。 全てのunittestファイルに以下を記載してもよいが手間。lynterが問題として検出することもある。 >|| import sys sys.path.append(r"<パッケージのディレクトリ>")