码迷,mamicode.com
首页 > 编程语言 > 详细

python unittest 运行失败后重试

时间:2017-10-29 21:16:06      阅读:491      评论:0      收藏:0      [点我收藏+]

标签:lte   移除   ddt   log   efi   wal   网上   close   files   

  最近为了实现自动化测试case运行失败后自动重试到处求教,自己研究了两三天以失败告终,最后在网上发现有大神重写了suite中的run方法说可以实现,但是不太适用我的项目,最终通过重写run_tests.py文件配合重写后的run方法实现了运行失败后重试。

run方法 源代码出处:http://blog.csdn.net/hqzxsc2006/article/details/50349664

 

下面是针对自己项目做的修改(关于最后邮件发送的就不说了):

suite.py

# -*- coding:utf-8 -*-
import unittest,time
from unittest.suite import _isnotsuite


class Suite(unittest.TestSuite):
    def run(self, result, debug=False):
        fail_count = 1
        class_num = 1
        topLevel = False
        if getattr(result, _testRunEntered, False) is False:
            result._testRunEntered = topLevel = True

        for test in self:
            case_num = 1
            if result.shouldStop:
                break
            success_flag = True
            while success_flag:
                if _isnotsuite(test):
                    self._tearDownPreviousClass(test, result)
                    self._handleModuleFixture(test, result)
                    self._handleClassSetUp(test, result)
                    result._previousTestClass = test.__class__
                    if (getattr(test.__class__, _classSetupFailed, False) or
                            getattr(result, _moduleSetUpFailed, False)):
                        if class_num > fail_count:
                            success_flag = False
                        else:
                            time.sleep(5)
                            result._previousTestClass = None
                            print %s Retrying init for %s times... % (test.__class__, class_num)
                            class_num += 1
                        continue

                if not debug:
                    test(result)
                    print 1
                else:
                    test.debug()

                if result.result[-1][0] == 1 or result.result[-1][0] == 2:  # 1为Failed,2为Error
                    if case_num > fail_count:
                        success_flag = False
                    else:
                        print %s is Failed ! Retrying %s times... % (test, case_num)
                        case_num += 1
                else:
                    success_flag = False

            if topLevel:
                self._tearDownPreviousClass(None, result)
                self._handleModuleTearDown(result)
                result._testRunEntered = False
        return result

    def removeTest(self, test):
        self._tests.remove(test)

新写了一个removeTest()方法用于移除测试用例集中的用例

runtests.py

# -*- coding:utf-8 -*-
import unittest,time,settings
from utilities.send_mail import send_mail,new_report
import HTMLTestRunner,suite,os
from BeautifulSoup import BeautifulSoup


def get_result_html(file_dir):
    L = []
    for root, dirs, files in os.walk(file_dir):
        for file in files:
            if os.path.splitext(file)[1] == .html:
                L.append(os.path.join(root, file))
    return L


def get_result_text():
    name = get_result_html(settings.RESULT_HTML_DIR)[-1]
    htmlfile = open(name, r)
    htmlpage = htmlfile.read()
    soup = BeautifulSoup(htmlpage)

    pass_div = soup.findAll(tr, attrs={class: passClass})
    pass_case_num = str(len(pass_div))

    file_obj = open(settings.RESULT_TEXT_DIR + /test_result.txt, wb+)
    file_obj.writelines(API TEST RESULT!)
    file_obj.writelines(\n\n\n\n\n\n\n\n\n)
    file_obj.writelines(SUCCESS: + pass_case_num)
    file_obj.writelines(\n\n\n\n\n\n\n\n\n)
    file_obj.writelines(FAILED: + str(int(len(case_name_list)) - int(pass_case_num)))
    file_obj.writelines(\n\n\n\n\n\n\n\n\n)
    file_obj.writelines(START_TIME: + str(start_time))
    file_obj.writelines(\n\n\n\n\n\n\n\n\n)
    file_obj.writelines(END_TIME: + str(end_time))
    file_obj.close()


if __name__ == __main__:
    start_time = time.strftime("%Y-%m-%d %H:%M:%S")
    test_dir = settings.API_TEST_CASE_DIR
    suite = suite.Suite()
    file_name = ./result/ + time.strftime("%Y_%m_%d_%H_%M_%S") + _ + settings.RESULT_FILE_NAME
    fp = open(file_name, wb+)
    runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title=settings.RESULT_TITLE,
                                               description=settings.RESULT_DESCRIPTION, verbosity=2)
    for case in test_dir:
        test_case = unittest.defaultTestLoader.discover(case,pattern=test_*,top_level_dir=os.path.abspath(./test_case/api_test_case/))
        case_name_list = []

        for x in [i._tests for i in test_case]:
            if not len(x) == 0:
                if len(x) == 1:
                    tds1 = x[0]
                    if not len(tds1._tests) == 0:
                        for y in tds1._tests:
                            case_name_list.append(y)

                elif len(x) == 2:
                    tds1 = x[0]
                    if not len(tds1._tests) == 0:
                        for y in tds1._tests:
                            case_name_list.append(y)
                    tds2 = x[1]
                    if not len(tds2._tests) == 0:
                        for y in tds2._tests:
                            case_name_list.append(y)

        for case_one in test_case._tests[0]._tests[1]:
            suite.addTest(case_one)
            runner.run(suite)
            suite.removeTest(case_one)
    fp.close()
    end_time = time.strftime("%Y-%m-%d %H:%M:%S")
    time.sleep(0.5)
    get_result_text()

    if not settings.ENV == dev:
        new_report = new_report(settings.RESULT_TEXT_DIR)
        time.sleep(0.5)
        send_mail(new_report)

因项目中case分类比较复杂,中间用了多个for循环获取case,实现的效果是,单个case添加到测试用例集里面,执行完之后,移除这个case,再添加下一个case。

缺点就是生成的html报告不太理想,无法汇总全部case的总结果。

技术分享

最终的总结果是通过BeautifulSoup获取html报告中成功的用例个数,再用总用例数减去成功用例数得到失败用例数,和总运行时长,汇总在test_result.txt中,再通过邮件发送运行情况报告。

python unittest 运行失败后重试

标签:lte   移除   ddt   log   efi   wal   网上   close   files   

原文地址:http://www.cnblogs.com/xaye/p/7751223.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!