本节将介绍做一个小工具,运行指定的测试用例或测试用例集合。
1. 我们要实现什么目标?
目标1:写一个python脚本,通过外部传参,来执行指定的测试用例 或测试用例集。大致包含两个参数:
- 参数1 run_mode:测试执行方式,有两个选项:run, run_session。run参数执行指定的测试用例, run_session参数执行指定的测试用例集;
- 参数2 test_content: 测试内容,当run_mode = run时,此参数指定一个测试用例文件名(.py), 当run_mode = run_session时,此参数指定测试数据目录/data/下的一个文本文件,其中罗列需要执行的测试用例文件名(.py)
目标2: 每次运行后,测试报告存放在指定的report 目录下, 测试报告目录生成规则为:
- 若run testcase.py, 生成测试报告目录名为testcase_时间戳,这样每执行一次测试 都是单独的一个目录,可以区分同一个测试用例执行多次的测试结果, 而且报告目录下除了存放html测试报告,还可以存放测试用例的执行过程截图,截图方法在BasePage类中已经实现;
- 若run_session session_filename, 生成测试报告目录为session_filename_时间戳,总的html报告在此目录下,其中包含session中所有test case的测试报告, 而session文件中每个测试用例又在其中单独有一个以测试用例文件名命名的报告目录,其中包含各自的测试过程截图。
2. 最重要的一步就是实现目标:
//sar.py
import unittest,time,sys,os
import importlib
from HTMLTestRunner import HTMLTestRunner
sys.path.append("../..")
from config.globalparameter import report_path, test_case_path
'''
param1 run_mode: run or run_session
param2 run_item: test case name or test session name
'''
def get_report_folder_path(testcase):
'''
param:
1.testcase: testcase name or test sessionname, eg:test_viewpage.py or session.txt
function: get the report folder absolute path.
eg: C:\Users\xxx\Desktop\test\test_records\report\test_viewpage_201907041748
'''
folder_name = os.path.basename(testcase).split(".")[0]
folder_name = folder_name+'_'+time.strftime('%Y%m%d%H%M%S', time.localtime())
repport_folder_path = report_path+folder_name
os.makedirs(repport_folder_path)
return repport_folder_path
def get_htmlreport_path(reportfolder, testcase):
'''
param:
1.reportfolder: absolute path, get from function 'def get_report_folder_path(testcase)'
2.testcase: testcase name, eg:test_viewpage.py
function: generate the html report name by case name, then combine the report folder name and the html report name.
eg: C:\Users\xxx\Desktop\test\test_records\report\test_viewpage_201907041748\test_viewpage.html
'''
casename = os.path.basename(testcase).split(".")[0]
htmlreport_name = casename + '.html'
htmlreport_path = reportfolder+'\\'+htmlreport_name
return htmlreport_path
def dynamic_import_testcase_module(module):
'''
param:
module: testcasename(exclude .py), eg:test_viewpage
dynamic import testcase module by the given testcase or session.
'''
modulename = "src.test_case."+module
return importlib.import_module(modulename)
def check_testcase_exist(testcase):
'''
testcase: eg:test_viewpage.py, if exists, return True, otherwise return False
'''
return os.path.exists(test_case_path+testcase)
def parse_testcase_session(session_file):
'''
check if all test cases included in sessionfile exist, and return a test cases list(testcase name without .py)
'''
list_testcase = []
fo = open(session_file, "r")
for line in fo:
casename = line.split('\n')[0]
if check_testcase_exist(casename) == False:
raise Exception("Test Case: %s not exist in /src/test_case/" % casename)
else:
casename = casename.split('.')[0]
list_testcase.append(casename)
return list_testcase
def run(suite, htmlreport_path):
'''
param:
suite: testsuite include all test cases need to be run.
htmlreport_path: generated by function 'def get_htmlreport_path(reportfolder, testcase)'
'''
# the test report path
fp = open(htmlreport_path, 'wb')
# define the test report
runner = HTMLTestRunner(stream=fp,
title='Test Report',
description= 'Test Case Running Status: ')
runner.run(suite) #run test
fp.close() #close test report
if __name__=="__main__":
run_mode = sys.argv[1]
run_item = sys.argv[2]
print "run mode is %s " % run_mode
report_foldername = get_report_folder_path(run_item)
print "report folder name is %s " % report_foldername
if run_mode == "run":
if not run_item.endswith(".py"):
raise Exception("Please specify a valid test case")
elif check_testcase_exist(run_item) == False:
raise Exception("The test case not exist in /src/test_case/")
else:
print "run test case is %s " % run_item
htmlreport_path = get_htmlreport_path(report_foldername,run_item)
print "html report path is %s " % htmlreport_path
testmodule_name = os.path.basename(run_item).split(".")[0]
module = dynamic_import_testcase_module(testmodule_name)
module.screenshots_path = report_foldername
suite1 = unittest.TestLoader().loadTestsFromModule(module)
suite = unittest.TestSuite([suite1])
elif run_mode == 'run_session':
list_testcases = []
list_suite = []
print "session file name is %s " % run_item
# list_testcases is a test cases list(test case name without .py)
htmlreport_path = get_htmlreport_path(report_foldername,run_item)
print "html report path is %s " % htmlreport_path
# parse the testsession file, then generate test case list.
list_testcases = parse_testcase_session(run_item)
print list_testcases #debug which test cases are included
print "All %d test cases need to be run." % len(list_testcases)
for case in list_testcases:
casereport_folder = report_foldername + '\\' + case
os.makedirs(casereport_folder)
testmodule_name = case
module = dynamic_import_testcase_module(testmodule_name)
module.screenshots_path = casereport_folder
case_suite = unittest.TestLoader().loadTestsFromModule(module)
list_suite.append(case_suite)
suite = unittest.TestSuite(list_suite)
else:
raise Exception("Usage: python sar.py [run|run_session] [testcase.py|session_file]")
run(suite,htmlreport_path)
运行测试用例: windows 打开开始菜单输入powershell,回车打开Windows Powershell窗口:
进入sar.py脚本所在目录,分别执行两种测试:运行测试用例 和 测试用例集。
1. 运行测试用例:输入命令: python .\sar.py run test_viewpage.py, 即可运行测试用例 test_viewpage.py
2. 运行测试集: 在\data\目录创建一个txt文件,其中包含要执行测试的测试脚本名称,一个测试用例写一行,注意:这些测试用例必须是在\src\test_case\中的,如下图:
然后再powershell终端输入命令运行测试集 :
脚本中加了很多调试的代码,运行时把报告目录以及要运行哪些测试用例都在终端显示出来了。 另外如上述所示,运行测试集返回结果为E,说明存在测试用例运行失败的。打开html测试报告,如下图所示,可以看到运行成功2个用例,失败1个用例:
对上述代码中需要解释的一点就是:通过这个小工具,其实就是通过解析传递进来的测试脚本名称, 实现动态地import test module, 再把这些test module 加入到testsuite中,最后运行测试。
这里要实现动态import test module,就要用到python的importlib标准库模块。参考:https://blog.csdn.net/helloxiaozhe/article/details/76578096