importsysimportosimportunittestfromunittestimportTestResult,TestLoaderimporttimeclassTagTestLoader(TestLoader):"""A TestLoader which handles additional __tags__ attributes for test functions. """def__init__(self,excludetags,randomizer=None):TestLoader.__init__(self)self.excludetags=excludetagsself.randomizer=randomizerdefgetTestCaseNames(self,testCaseClass):"""Gets only the tests, which are not within the tag exclusion. The method overrides the original TestLoader.getTestCaseNames() method, so we need to keep them in sync on updates. """defisTestMethod(attrname,testCaseClass=testCaseClass,prefix=self.testMethodPrefix):ifnotattrname.startswith(prefix):returnFalseifnothasattr(getattr(testCaseClass,attrname),"__call__"):returnFalseifhasattr(getattr(testCaseClass,attrname),"__tags__"):# Tagged test methodtags=getattr(getattr(testCaseClass,attrname),"__tags__")fortintags:iftinself.excludetags:returnFalsereturnTrueifhasattr(testCaseClass,"__tags__"):tags=getattr(testCaseClass,"__tags__")fortintags:iftinself.excludetags:return[]testFnNames=list(filter(isTestMethod,dir(testCaseClass)))cmpkey=getattr(unittest,"_CmpToKey",None)or \
getattr(unittest,"CmpToKey",None)ifself.randomizer:self.randomizer.shuffle(testFnNames)elifself.sortTestMethodsUsing:ifcmpkey:testFnNames.sort(key=cmpkey(self.sortTestMethodsUsing))else:testFnNames.sort()returntestFnNamesclassSimpleTestResult(TestResult):"""A simple TestResult class with output capabilities. """def__init__(self,stream=sys.stderr,verbose=False,countcall=None):TestResult.__init__(self)self.stream=streamself.duration=0self.verbose=verboseself.countcall=countcalldefaddSkip(self,test,reason):TestResult.addSkip(self,test,reason)ifself.verbose:self.stream.write("SKIPPED: %s [%s]%s"%(test,reason,os.linesep))self.stream.flush()self.countcall()defaddSuccess(self,test):TestResult.addSuccess(self,test)ifself.verbose:self.stream.write("OK: %s%s"%(test,os.linesep))self.stream.flush()self.countcall()defaddError(self,test,err):TestResult.addError(self,test,err)ifself.verbose:self.stream.write("ERROR: %s%s"%(test,os.linesep))self.stream.flush()self.countcall()defaddFailure(self,test,err):TestResult.addFailure(self,test,err)ifself.verbose:self.stream.write("FAILED: %s%s"%(test,os.linesep))self.stream.flush()self.countcall()classSimpleTestRunner(object):def__init__(self,stream=sys.stderr,verbose=False):self.stream=streamself.verbose=verbosedefrun(self,test,countcall):result=SimpleTestResult(self.stream,self.verbose,countcall)starttime=time.time()test(result)endtime=time.time()result.duration=endtime-starttimereturnresult