5 import unittest2 as unittest
8 from jinja2 import Environment, FileSystemLoader
10 from itest import xmlparser
11 from itest.conf import settings
12 from itest.case import TestCase
14 log = logging.getLogger(os.path.splitext(os.path.basename(__file__))[0])
19 Load tests from a single test select pattern `sel`
21 suiteClass = unittest.TestSuite
23 return isinstance(ret, suiteClass) or \
24 isinstance(ret, TestCase)
30 for pattern in suite_patterns.all():
34 ret = pattern.load(sel)
40 elif isinstance(ret, list):
49 class TestLoader(unittest.TestLoader):
51 def loadTestsFromModule(self, _module, _use_load_tests=True):
53 return load_case(settings.env_root)
54 return self.suiteClass()
56 def loadTestsFromName(self, name, module=None):
57 return load_case(name)
60 class AliasPattern(object):
61 '''dict key of settings.SUITES is alias for its value'''
64 if sel in settings.SUITES:
65 return settings.SUITES[sel]
68 class FilePattern(object):
69 '''test from file name'''
72 if not os.path.isfile(name):
75 template_dirs = [os.path.abspath(os.path.dirname(name))]
76 if settings.cases_dir:
77 template_dirs.append(settings.cases_dir)
78 jinja2_env = Environment(loader=FileSystemLoader(template_dirs))
79 template = jinja2_env.get_template(os.path.basename(name))
80 text = template.render()
82 if isinstance(text, unicode):
83 text = text.encode('utf8')
84 # template returns unicode
85 # but xml parser only accepts str
86 # And we can only assume it's utf8 here
88 data = xmlparser.Parser().parse(text)
90 raise Exception("Can't load test case from %s" % name)
91 return TestCase(os.path.abspath(name), data)
94 class DirPattern(object):
95 '''find all tests recursively in a dir'''
98 if os.path.isdir(top):
99 return list(self._walk(top))
101 def _walk(self, top):
102 for current, _dirs, nondirs in os.walk(top):
104 if name.endswith('.case'):
105 yield os.path.join(current, name)
108 class ComponentPattern(object):
109 '''tests from a component name'''
114 def guess_components():
115 if not settings.env_root:
118 for base in os.listdir(settings.cases_dir):
119 full = os.path.join(settings.cases_dir, base)
120 if os.path.isdir(full):
125 def is_component(cls, comp):
126 if cls._components is None:
127 cls._components = cls.guess_components()
128 return comp in cls._components
130 def load(self, comp):
131 if self.is_component(comp):
132 return os.path.join(settings.cases_dir, comp)
135 class InversePattern(object):
136 '''string starts with "!" is the inverse of string[1:]'''
139 if sel.startswith('!'):
141 comps = ComponentPattern.guess_components()
142 if ComponentPattern.is_component(comp):
143 return [c for c in comps if c != comp]
144 # if the keyword isn't a component name, then it is useless
148 class IntersectionPattern(object):
149 '''use && load intersection set of many parts'''
151 loader_class = TestLoader
154 if sel.find('&&') <= 0:
157 def intersection(many):
163 inter.intersection_update(each)
166 loader = self.loader_class()
167 many = [load_case(part) for part in sel.split('&&')]
169 return loader.suiteClass(intersection(many))
172 class _SuitePatternRegister(object):
177 def register(self, cls):
178 self._patterns.append(cls)
181 return self._patterns
184 def register_default_patterns():
185 for pattern in (AliasPattern,
192 suite_patterns.register(pattern)
194 suite_patterns = _SuitePatternRegister()
195 register_default_patterns()