Browse files

Add command flag to allow the creation of the MAYA_APP_DIR for testing.

This allows the clean MAYA_APP_DIR to be created when running tests from PyCharm.
Also add new file functionality to TestCase for PyCharm run tests since new file only
happened in the custom TestResult class.
  • Loading branch information...
chadmv committed Mar 2, 2016
1 parent 0f6e6d8 commit 6c7999839367d1b540712bc517144a3726812edb
Showing with 44 additions and 4 deletions.
  1. +27 −3 bin/
  2. +17 −1 scripts/cmt/test/
@@ -8,9 +8,11 @@
python -m 2016
import argparse
import errno
import os
import platform
import shutil
import stat
import subprocess
import tempfile
import uuid
@@ -50,7 +52,7 @@ def mayapy(maya_version):
return python_exe
def create_clean_maya_app_dir():
def create_clean_maya_app_dir(directory=None):
"""Creates a copy of the clean Maya preferences so we can create predictable results.
@return: The path to the clean MAYA_APP_DIR folder.
@@ -59,24 +61,46 @@ def create_clean_maya_app_dir():
temp_dir = tempfile.gettempdir()
if not os.path.exists(temp_dir):
dst = os.path.join(temp_dir, 'maya_app_dir{0}'.format(uuid.uuid4()))
dst = directory if directory else os.path.join(temp_dir, 'maya_app_dir{0}'.format(str(uuid.uuid4())))
if os.path.exists(dst):
shutil.rmtree(dst, ignore_errors=False, onerror=remove_read_only)
shutil.copytree(app_dir, dst)
return dst
def remove_read_only(func, path, exc):
"""Called by shutil.rmtree when it encounters a readonly file.
:param func:
:param path:
:param exc:
excvalue = exc[1]
if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
os.chmod(path, stat.S_IRWXU| stat.S_IRWXG| stat.S_IRWXO) # 0777
raise RuntimeError('Could not remove {0}'.format(path))
def main():
parser = argparse.ArgumentParser(description='Runs unit tests for a Maya module')
parser.add_argument('-m', '--maya',
help='Maya version',
parser.add_argument('-mad', '--maya-app-dir',
help='Just create a clean MAYA_APP_DIR and exit')
pargs = parser.parse_args()
mayaunittest = os.path.join(CMT_ROOT_DIR, 'scripts', 'cmt', 'test', '')
cmd = [mayapy(pargs.maya), mayaunittest]
if not os.path.exists(cmd[0]):
raise RuntimeError('Maya {0} is not installed on this system.'.format(pargs.maya))
maya_app_dir = create_clean_maya_app_dir()
app_directory = pargs.maya_app_dir
maya_app_dir = create_clean_maya_app_dir(app_directory)
if app_directory:
# Create clean prefs
os.environ['MAYA_APP_DIR'] = maya_app_dir
# Clear out any MAYA_SCRIPT_PATH value so we know we're in a clean env.
@@ -39,6 +39,9 @@ def test_create_sphere(self):
import logging
import maya.cmds as cmds
# The environment variable that signifies tests are being run with the custom TestResult class.
def run_tests(directories=None, test=None, test_suite=None):
"""Run all the tests in the given paths.
@@ -133,7 +136,7 @@ class Settings(object):
# Specifies where files generated during tests should be stored
# Use a uuid subdirectory so tests that are running concurrently such as on a build server
# do not conflict with each other.
temp_dir = os.path.join(tempfile.gettempdir(), str(uuid.uuid4()))
temp_dir = os.path.join(tempfile.gettempdir(), 'mayaunittest', str(uuid.uuid4()))
# Controls whether temp files should be deleted after running all tests in the test case
delete_files = True
@@ -239,6 +242,8 @@ def delete_temp_files(cls):
if os.path.exists(f):
cls.files_create = []
if os.path.exists(Settings.temp_dir):
def get_temp_filename(cls, file_name):
@@ -271,6 +276,12 @@ def assertListAlmostEqual(self, first, second, places=7, msg=None, delta=None):
for a, b in zip(first, second):
self.assertAlmostEqual(a, b, places, msg, delta)
def tearDown(self):
if Settings.file_new and CMT_TESTING_VAR not in os.environ.keys():
# If running tests without the custom runner, like with PyCharm, the file new of the TestResult class isn't
# used so call file new here
cmds.file(f=True, new=True)
class TestResult(unittest.TextTestResult):
"""Customize the test result so we can do things like do a file new between each test and suppress script
@@ -283,6 +294,9 @@ def __init__(self, stream, descriptions, verbosity):
def startTestRun(self):
"""Called before any tests are run."""
super(TestResult, self).startTestRun()
# Create an environment variable that specifies tests are being run through the custom runner.
os.environ[CMT_TESTING_VAR] = '1'
if Settings.buffer_output:
# Disable any logging while running tests. By disabling critical, we are disabling logging
@@ -298,6 +312,8 @@ def stopTestRun(self):
if Settings.delete_files and os.path.exists(Settings.temp_dir):
del os.environ[CMT_TESTING_VAR]
super(TestResult, self).stopTestRun()
def stopTest(self, test):

0 comments on commit 6c79998

Please sign in to comment.