Пример #1
0
    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)
Пример #2
0
    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
Пример #3
0
    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