def run(self, testcase, testresult_factory): '''执行一个测试用例 :param testcase: 执行的测试用例 :type testcase: TestCase :param testresult_factory: 测试结果工厂 :type testresult_factory: ITestResultFactory :returns : 测试结果 :rtype TestResult/TestResultCollection - 测试结果 ''' passed = True if not hasattr(testcase, "repeat"): passed = False err_msg = "使用RepeatTestCaseRunner的测试用例需要设置类属性:repeat" elif testcase.repeat <= 0: passed = False err_msg = "使用RepeatTestCaseRunner的测试用例的类属性'repeat'必须大于0" if not passed: with ThreadGroupScope('%s:%s' % (testcase.test_name, id(self))): result = testresult_factory.create(testcase) ThreadGroupLocal().testcase = testcase ThreadGroupLocal().testresult = result result.begin_test(testcase) result.error(err_msg) result.end_test() return result passed = True results = [] for i in range(testcase.repeat): testcase.iteration = i case_result = self._case_runner_class().run( testcase, testresult_factory) passed &= case_result.passed results.append(case_result) if not passed: break return TestResultCollection(results, passed)
def run(self, testcase, testresult_factory): '''执行一个测试用例 :param testcase: 执行的测试用例 :type testcase: TestCase :param testresult_factory: 测试结果工厂 :type testresult_factory: ITestResultFactory :rtype: TestResult/TestResultCollection - 测试结果 ''' # 临时方案是disable gc后kill掉程序,在enable gc。后续这里 # 需要重新考虑已独立进程来执行测试用例。 self._stop_run = False self._testcase = testcase self._testresult = testresult_factory.create(testcase) self._subtasks = collections.deque( ['init_test', 'pre_test', 'run_test', 'post_test', 'clean_test']) with ThreadGroupScope('%s:%s' % (self._testcase.test_name, id(self))): ThreadGroupLocal().testcase = self._testcase ThreadGroupLocal().testresult = self._testresult self._testresult.begin_test(self._testcase) self.setup(self._testcase, self._testresult) if isinstance(self._testcase.timeout, int) or isinstance( self._testcase.timeout, float): timeout = self._testcase.timeout * 60 else: timeout = 60 test_thread = threading.Thread(target=self._thread_run) test_thread.daemon = True test_thread.start() test_thread.join(timeout) if test_thread.is_alive(): self._stop_run = True try: thread_traceback = self._get_current_traceback(test_thread) except: self._testresult.log_record(EnumLogLevel.TESTTIMEOUT, '测试用例执行超时') else: self._testresult.log_record( EnumLogLevel.TESTTIMEOUT, '测试用例执行超时,抓取测试线程当前堆栈', dict(traceback=thread_traceback)) # 启动线程执行可能未执行的postTest和cleanTest cleanup_thread = threading.Thread(target=self._thread_cleanup) cleanup_thread.daemon = True cleanup_thread.start() cleanup_thread.join(self.CLEANUP_TIMEOUT) if cleanup_thread.is_alive(): try: thread_traceback = self._get_current_traceback( cleanup_thread) except: self._testresult.log_record(EnumLogLevel.TESTTIMEOUT, '测试用例执行超时时清理超时') else: self._testresult.log_record( EnumLogLevel.TESTTIMEOUT, '测试用例执行超时时清理超时,抓取清理线程当前堆栈', dict(traceback=thread_traceback)) else: if self._error: raise RuntimeError("用例执行线程异常:\n%s" % smart_text(self._error)) else: if self._error: raise RuntimeError("用例执行线程异常:\n%s" % smart_text(self._error)) self.teardown(self._testcase, self._testresult) self._testresult.end_test() # gc.enable() # gc.collect() return self._testresult
def run(self, testcase, testresult_factory): '''执行一个测试用例 :param testcase: 执行的测试用例 :type testcase: TestCase :param testresult_factory: 测试结果工厂 :type testresult_factory: ITestResultFactory :rtype: TestResult/TestResultCollection - 测试结果 ''' #2011/08/31 pear is_alive是一个方法,非变量 #2012/01/05 banana 当被测程序hang住,python的垃圾回收释放远程COM对象也会hang。 # 临时方案是disable gc后kill掉程序,在enable gc。后续这里 # 需要重新考虑已独立进程来执行测试用例。 #2012/06/07 pear 如果测试用例超时,调用postTest,否则无法释放资源,也无法看到申请的帐号资源是什么。 self._testcase = testcase self._testresult = testresult_factory.create(testcase) # if type(testcase).__dict__.has_key('run_test'): #使用新的代码风格的接口 # self._subtasks = collections.deque(['init_test', 'pre_test', 'run_test', 'post_test', 'clean_test']) # else: #兼容老的代码风格的接口 # self._subtasks = collections.deque(['initTest', 'preTest', 'runTest', 'postTest', 'cleanTest']) self._subtasks = collections.deque( ['initTest', 'preTest', 'runTest', 'postTest', 'cleanTest']) #import gc #gc.disable() with ThreadGroupScope('%s:%s' % (self._testcase.test_name, id(self))): ThreadGroupLocal().testcase = self._testcase ThreadGroupLocal().testresult = self._testresult self._testresult.begin_test(self._testcase) self.setup(self._testcase, self._testresult) if isinstance(self._testcase.timeout, int) or isinstance( self._testcase.timeout, float): timeout = self._testcase.timeout * 60 else: timeout = 60 test_thread = threading.Thread(target=self._thread_run) test_thread.daemon = True test_thread.start() test_thread.join(timeout) if test_thread.is_alive(): self._stop_run = True try: thread_traceback = self._get_current_traceback(test_thread) except: self._testresult.log_record(EnumLogLevel.TESTTIMEOUT, '测试用例执行超时') else: self._testresult.log_record( EnumLogLevel.TESTTIMEOUT, '测试用例执行超时,抓取测试线程当前堆栈', dict(traceback=thread_traceback)) #启动线程执行可能未执行的postTest和cleanTest,只给15秒的窗口 cleanup_thread = threading.Thread(target=self._thread_cleanup) cleanup_thread.daemon = True cleanup_thread.start() cleanup_thread.join(self.CLEANUP_TIMEOUT) if cleanup_thread.is_alive(): try: thread_traceback = self._get_current_traceback( cleanup_thread) except: self._testresult.log_record(EnumLogLevel.TESTTIMEOUT, '测试用例执行超时时清理超时') else: self._testresult.log_record( EnumLogLevel.TESTTIMEOUT, '测试用例执行超时时清理超时,抓取清理线程当前堆栈', dict(traceback=thread_traceback)) else: if self._error: raise RuntimeError("用例执行线程异常:\n%s" % self._error) else: if self._error: raise RuntimeError("用例执行线程异常:\n%s" % self._error) self.teardown(self._testcase, self._testresult) self._testresult.end_test() #gc.enable() #gc.collect() return self._testresult