python unittest 運行失敗後重試
阿新 • • 發佈:2017-10-29
for 郵件 lose npr mlp os.path es2017 not tail
最近為了實現自動化測試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 _isnotsuiteclass 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 運行失敗後重試