1import sys 2import imp 3import os 4import fnmatch 5import sys 6sys.stderr.write("Warning: You are using test runners in legacy mode\n. " 7 "That means you have 'python.tests.enableUniversalTests=false' in registry.\n" 8 "This mode will be dropped in 2021. Consider removing this entry from registry and migrating to new test runners") 9roots = sys.path[:] 10 11helpers_dir = os.getenv("PYCHARM_HELPERS_DIR", sys.path[0]) 12if sys.path[0] != helpers_dir: 13 sys.path.insert(0, helpers_dir) 14 15from tcunittest import TeamcityTestRunner 16from nose_helper import TestLoader, ContextSuite 17from pycharm_run_utils import import_system_module 18from pycharm_run_utils import adjust_sys_path 19from pycharm_run_utils import debug, getModuleName, PYTHON_VERSION_MAJOR 20 21adjust_sys_path() 22 23os = import_system_module("os") 24re = import_system_module("re") 25 26modules = {} 27 28def loadSource(fileName): 29 baseName = os.path.basename(fileName) 30 moduleName = os.path.splitext(baseName)[0] 31 32 if os.path.isdir(fileName): 33 fileName = fileName.rstrip('/\\') + os.path.sep 34 35 # for users wanted to run unittests under django 36 # because of django took advantage of module name 37 settings_file = os.getenv('DJANGO_SETTINGS_MODULE') 38 39 if settings_file and moduleName == "models": 40 baseName = os.path.realpath(fileName) 41 moduleName = ".".join((baseName.split(os.sep)[-2], "models")) 42 else: 43 path = fileName 44 for p in roots: 45 # Python 2.6+ 46 try: 47 rel_path = os.path.relpath(fileName, start=p) 48 if rel_path.find('..') == -1 and len(rel_path) < len(path): 49 path = rel_path 50 except: 51 pass # relpath can raise an error in case of different drives for a path and start on Windows 52 53 if path.endswith('.py'): 54 path = path[0:-3] 55 56 moduleName = path.replace('/', '.').replace('\\', '.') 57 58 if moduleName in modules and len(sys.argv[1:-1]) == 1: # add unique number to prevent name collisions 59 cnt = 2 60 prefix = moduleName 61 while getModuleName(prefix, cnt) in modules: 62 cnt += 1 63 moduleName = getModuleName(prefix, cnt) 64 65 debug("/ Loading " + fileName + " as " + moduleName) 66 67 try: 68 module = imp.load_source(moduleName, fileName) 69 except SystemError: # probably failed because of the relative imports 70 # first we import module with all its parents 71 __import__(moduleName) 72 73 # then load it by filename to be sure it is the one we need 74 module = imp.load_source(moduleName, fileName) 75 76 modules[moduleName] = module 77 return module 78 79def walkModules(modulesAndPattern, dirname, names): 80 modules = modulesAndPattern[0] 81 pattern = modulesAndPattern[1] 82 # fnmatch converts glob to regexp 83 prog_list = [re.compile(fnmatch.translate(pat.strip())) for pat in pattern.split(',')] 84 for name in names: 85 for prog in prog_list: 86 if name.endswith(".py") and prog.match(name): 87 modules.append(loadSource(os.path.join(dirname, name))) 88 89 90# For default pattern see https://docs.python.org/2/library/unittest.html#test-discovery 91def loadModulesFromFolderRec(folder, pattern="test*.py"): 92 modules = [] 93 # fnmatch converts glob to regexp 94 prog_list = [re.compile(fnmatch.translate(pat.strip())) for pat in pattern.split(',')] 95 for root, dirs, files in os.walk(folder): 96 files = [f for f in files if not f[0] == '.'] 97 dirs[:] = [d for d in dirs if not d[0] == '.'] 98 for name in files: 99 for prog in prog_list: 100 if name.endswith(".py") and prog.match(name): 101 modules.append(loadSource(os.path.join(root, name))) 102 return modules 103 104testLoader = TestLoader() 105all = ContextSuite() 106pure_unittest = False 107 108def setLoader(module): 109 global testLoader, all 110 try: 111 module.__getattribute__('unittest2') 112 import unittest2 113 114 testLoader = unittest2.TestLoader() 115 all = unittest2.TestSuite() 116 except: 117 pass 118 119if __name__ == "__main__": 120 arg = sys.argv[-1] 121 if arg == "true": 122 import unittest 123 124 testLoader = unittest.TestLoader() 125 all = unittest.TestSuite() 126 pure_unittest = True 127 128 if len(sys.argv) == 2: # If folder not provided, we need pretend folder is current 129 sys.argv.insert(1, ".") 130 131 options = {} 132 for arg in sys.argv[1:-1]: 133 arg = arg.strip() 134 if len(arg) == 0: 135 continue 136 137 if arg.startswith("--"): 138 options[arg[2:]] = True 139 continue 140 141 a = arg.split("::") 142 if len(a) == 1: 143 # From module or folder 144 a_splitted = a[0].split("_args_separator_") # ";" can't be used with bash, so we use "_args_separator_" 145 if len(a_splitted) != 1: 146 # means we have pattern to match against 147 if os.path.isdir(a_splitted[0]): 148 debug("/ from folder " + a_splitted[0] + ". Use pattern: " + a_splitted[1]) 149 modules = loadModulesFromFolderRec(a_splitted[0], a_splitted[1]) 150 else: 151 if os.path.isdir(a[0]): 152 debug("/ from folder " + a[0]) 153 modules = loadModulesFromFolderRec(a[0]) 154 else: 155 debug("/ from module " + a[0]) 156 modules = [loadSource(a[0])] 157 158 for module in modules: 159 all.addTests(testLoader.loadTestsFromModule(module)) 160 161 elif len(a) == 2: 162 # From testcase 163 debug("/ from testcase " + a[1] + " in " + a[0]) 164 module = loadSource(a[0]) 165 setLoader(module) 166 167 if pure_unittest: 168 all.addTests(testLoader.loadTestsFromTestCase(getattr(module, a[1]))) 169 else: 170 all.addTests(testLoader.loadTestsFromTestClass(getattr(module, a[1])), 171 getattr(module, a[1])) 172 else: 173 # From method in class or from function 174 debug("/ from method " + a[2] + " in testcase " + a[1] + " in " + a[0]) 175 module = loadSource(a[0]) 176 setLoader(module) 177 178 if a[1] == "": 179 # test function, not method 180 all.addTest(testLoader.makeTest(getattr(module, a[2]))) 181 else: 182 testCaseClass = getattr(module, a[1]) 183 try: 184 all.addTest(testCaseClass(a[2])) 185 except: 186 # class is not a testcase inheritor 187 all.addTest( 188 testLoader.makeTest(getattr(testCaseClass, a[2]), testCaseClass)) 189 190 debug("/ Loaded " + str(all.countTestCases()) + " tests") 191 TeamcityTestRunner().run(all, **options) 192