🐈
起動中のMayaでPytestを実行する
経緯
MayaでPytestを実行する時は下記の様にコマンドプロンプトで実行する。
mayapy -m pytest
しかし、この方法だと毎回standalone起動が必要となり、テストに時間がかかるため、起動中のMayaでPytestを実行したくなった。
実行不可
普通にスクリプトエディターで実行しても下記エラーが発生し、できない。
import pytest
pytest.main(["テストフォルダ"])
# INTERNALERROR> self.isatty = file.isatty()
# INTERNALERROR> AttributeError: 'maya.Output' object has no attribute 'isatty'
原因
これはMayaがstdoutクラスを独自設定しているため。
import sys
sys.stdout
# 結果: <maya.Output object at 0x000001F42EE539B0>
解決方法
ドンピシャな方法がissueに上がっていて、StdOutクラスをラップしてあげれば良さそう。
コード
上記のissueを参考に書いた物がこちら。
import sys
import pytest
from maya import cmds
class MayaStdOutWrapper:
"""stdoutをラップする
"""
def __init__(self, stdout):
self._stdout = stdout
def __getattr__(self, item):
if item == "isatty":
return self.isatty
else:
return getattr(self._stdout, item)
def isatty(self):
return False
def reload_tests(test_packages_name: str):
"""なくても動くが
pytestを一度実行した前にリロードしないと修正内容が反映されない
"""
for module_name in list(sys.modules):
if test_packages_name in module_name:
del sys.modules[module_name]
print(f"deleted {module_name}")
if not isinstance(sys.stdout, MayaStdOutWrapper):
sys.stdout = MayaStdOutWrapper(sys.stdout)
reload_tests("テストパッケージ名")
pytest.main(["-v", "実行したいテストフォルダ"])
余談
pytestを実行したいテストフォルダ以下に「conftest.py」というファイル名で
関数ごとにMayaシーンを新規で開くフックを書いて置くとテストがしやすい。
公式
conftest.py
import pytest
from maya import cmds
@pytest.fixture(autouse=True)
def setup():
print("テスト関数実行前")
cmds.file(newFile=True, force=True)
yield
print("テスト関数実行後")
Discussion