Execute Tests in DCCs
Until now, we executed our tests only in a standard Python interpreter. However, visual effects pipelines often consist of code that needs to run inside a DCC like Maya, Houdini, or Nuke. These DCCs ship with their own Python interpreter and can execute Python code.
Examples for code running inside a DCC are pipeline integrations or DCC tools. This code often depends on the Python API of the DCCs and has to run inside the corresponding DCC. Outside of the DCC their Python API is not available. Because also the tests depend on the DCC Python API, they have to run inside the DCC.
Visual effects pipelines often use Python, because it enables the developers to write code one time and run the same code in any DCC supporting Python. But support for multiple DCCs is challenging since each DCC interpreter has some little differences.
For these reasons, we must be able to execute tests inside DCCs, so we find any issues before we deploy our code.
Execute tests in DCCs
To execute tests inside DCCs, we are faced with two challenges:
- Make dependencies available such as pytest or mock
- Launch the DCC and start the testing framework
Making the dependencies available is straightforward. We can just put them on the $PYTHONPATH.
How to launch the DCC and start the testing framework differs from DCC to DCC. In general, the DCC ist started in batch mode without GUI, and a wrapper script is responsible for launching the testing framework. When starting the DCCs in batch mode, the tests can be executed on a Build Server, which are mostly headless and don’t have a UI.
Here are examples for the most common DCCs:
Maya
For Maya, we can use mayapy to launch Maya in batch mode. We can pass a wrapper script as command line argument to mayapy. In case of Maya, the wrapper script needs to initialize Maya Standalone first and can do this by importing PyMEL, see here for reasons. Once Maya Standalone is initialized, we can launch the test framework.
Nuke
For Nuke, we can start Nuke with the -t
command line parameter and pass a path to the wrapper script.
Inside the wrapper script, we don’t have to do anything special; we just have to launch the test framework.
Houdini
For Houdini, we can use the hython executable and pass a path to the wrapper script. Inside the wrapper script, we don’t have to do anything special; we just have to launch the test framework.
The Wrapper Script
Here is an example wrapper script named run_tests.py
:
import sys
import pytest
MAYA = False
NUKE = False
HOUDINI = False
try:
import pymel.core as pm
MAYA = True
except ImportError:
pass
try:
import nuke
NUKE = True
except ImportError:
pass
try:
import hou
HOUDINI = True
except ImportError:
pass
def get_current_interpreter():
# type: () -> str
global MAYA, NUKE, HOUDINI
if MAYA:
return "maya"
elif NUKE:
return "nuke"
elif HOUDINI:
return "houdini"
else:
return "standalone_python"
if __name__ == "__main__":
interpreter = get_current_interpreter()
print("running tests in {}...".format(interpreter))
pytest.main(sys.argv[1:])
Assuming the wrapper script is saved in the current directory and there is a virtualenv called venv in the current directory, you can launch tests in the DCCs like this:
Maya
Nuke
-nc
parameter to start Nuke in non-commercial mode.
Houdini
vfx-testrunner
If you don’t want to write your own wrapper script, the vfx-testrunner project already contains ready-to-go solutions to execute tests inside a DCC. You can find it on Github: https://github.com/PaulSchweizer/vfx-testrunner