为什么要学习接口自动化测试
①接口变动小,故保证了自动化测试代码的使用期限,有点一劳永逸的感觉
②避免重复劳动,减少人力、节省时间
因python语言较易入手,所以我主要使用python+unittest框架进行接口自动化测试程序开发。
写接口自动化测试代码过程中,可能遇到的问题汇总如下:
①总体的接口测试框架如何设计?
②unittest框架如何组织、加载及执行测试用例;
③使用unittest执行会单条测试用例后,如何执行多条测试用例?如有一个记录测试数据的Excel表,如何将表中的数据参数化给testcase。最简单的思路就是使用for循环遍历excel表中的数据,传给testcase,但这个过程只能在一个testcase中进行,即只能算做执行了一条testcase,我们想要的是结果是有几条数据,就执行几个testcase;
④如何记录日志?记录执行程序过程中产生的日志,便于问题分析与定位;
⑤如何可视化测试结果?执行tesecase成功了多少?失败了多少?哪一条成功,哪一条失败?如何查看每条testcase执行时产生的日志
对于第一个问题,我们可以使用如下测试框架目录结构:
APITest
Interface
req.py
requestFengZhuang.py
Public
log.py
HTMLRunner.py
read_excel.py
panduan.py
xmltojson.py
Testsuites
test_add.py
test_sub.py
testdata
接口测试用例.xlsx
log
test_reports
run_interface.py
简要解释如下:
Interface:存放api接口封装类。其中,req.py中存放的是对requests模块post及get请求的初步封装,requestFengZhuang.py是对req.py的进一步封装,负责对传入的请求方式、请求连接、请求数据等参数进行逻辑处理,为外部请求提供一个统一的接口。
Public:存放支撑类代码,如读取excel的类、写日志的类、生成测试报告的类、文件格式转化的类等都放在这里
Testsuites:存放测试类文件。其中,测试类指继承自unittest.TestCase的类
testdata:存放编写的测试用例文件,如excel,用于参数化Testsuites中的testcase
log:存放日志文件,程序运行测试用例过程中生成的日志均存放在该文件中
test_reports:存放生成的测试报告,格式一般为html
run_interface.py:主驱动程序,类似于c++中的main函数
对于第二个问题“unittest框架如何组织、加载及执行测试用例“,我们遇到的首要问题是:unittest如何用代码实现待测试的用例?
通过查阅文档,我们可以知道,它是通过定义测试类的方式,在类方法中实现待测试的用例。为了方便我们理解,贴出了部分示例代码。
1 import unittest 2 3 class APITest(unittest.TestCase): 4 5 def test_a(self): 6 print("a")
其中,测试类:APITest(继承unittest.TestCase)
类方法:test_a,必须以'test_'开头实现的测试用例,才能被执行。该方法的执行结果就是测试用例的执行结果,通常用assert断言实际结果和预期结果是否一致,进而来判断测试用例执行是否成功。
具体断言所用方法不再详细列出,可在网上查找unittest如何断言。
备注:一个testcase中,可以写多个断言,只要一个结果为false,则这个testcase就为false。如一个测试用例包括前置条件和后置条件,要断言多个结果,才能判断测试用例是否通过
用unittest实现了测试用例后,如何运行测试用例呢?
unittest提供了8种加载测试用例的方法以及运行测试用例的方法。
①加载测试用例的方式(8种)
1 unittest.TestLoader().loadTestsFromTestCase(测试类) 2 unittest.TestLoader().loadTestsFromName() 3 unittest.TestLoader().loadTestsFromNames() 4 unittest.TestLoader().loadTestsFromModule() 5 unittest.TestLoader().discover() 两种 6 suite=unitest.TestSuite() suite.addTest(Testdemo('test_a')) 7 unittest.main()
②运行测试用例的方法
1 unittest.TextTestRunner().run(testcase)
通过以上学习,我们应该学会了使用unittest执行单条测试用例,那如何执行多条测试用例呢?测试时,我们不会只执行一条测试用例,当然,我们可以多写几个测试类方法,即我们想要执行几条测试用例,就得写几个测试类方法,这样的代码开发、维护及使用都很不方便,这种方法显然不能适用于真实的测试环境。那还有什么方法呢?通过分析接口测试的过程,我们得知,接口请求过程都是一样的,不一样的主要是接口地址、参数、请求方式及预期结果,也就是说我们可以只写一个测试类方法,主体代码为请求过程,不同的测试用例只是参数不同而已,数据驱动正好可以实现我们的要求。在python中,我们主要使用ddt模块来实现数据驱动,使用时需在测试类前加@ddt.ddt,需要数据驱动的测试用例部分加@ddt.data(*excel_data),excel_data数据可以是从excel中读取到的数据,格式为嵌套字典的列表,[{'url':'','id':''},{'url':'','id':''}]
1 data_test=makedata() 2 @ddt.ddt 3 class TestTcp(unittest.TestCase): 4 '''test_class''' 5 @classmethod 6 def setUpClass(cls):#类中最先执行 7 pass 8 9 @classmethod 10 def tearDownClass(cls): #类中最后执行 11 pass 12 13 def setUp(self): 14 print("start") 15 def tearDown(self): 16 print("end") 17 18 19 20 @ddt.data(*data_test) 21 def test_request_api(self,data_test): 22 self.doc=data_test['title'] 23 self.assertEqual(result, 'pass', msg="预期和返回结果不一致")
在执行测试用例后,虽然结果显示成功/失败,但我们如何得知测试用例为何成功/失败,成功或失败的依据是什么,以方便开发/测试人员定位问题。这就需要日志功能,在python中,我们主要使用logbook模块来实现日志记录功能。
①首先,我们编写log.py模块封装该功能,包括设置日志存放路径、设置日志格式等,具体代码如下:
1 # -*- coding: utf-8 -*- 2 3 import logbook 4 from logbook import TimedRotatingFileHandler,set_datetime_format 5 from logbook.more import ColorizedStderrHandler 6 import os 7 8 check_path="." 9 LOG_DIR_NAME="log" 10 LOG_PATH=os.path.join(check_path,LOG_DIR_NAME) 11 if not os.path.exists(LOG_PATH): 12 os.makedirs(LOG_PATH) 13 14 def get_logger(name="Interface",level=""): 15 set_datetime_format('local') 16 17 ColorizedStderrHandler(bubble=False,level=level).push_thread() 18 TimedRotatingFileHandler( 19 os.path.join(LOG_PATH,"%s.log"%name),date_format="%Y-%m-%d-%H",bubble=True,encoding='utf-8' 20 ).push_thread() 21 return logbook.Logger(name) 22 23 LOG=get_logger(level="INFO") 24 25 def Logger(param): 26 27 def wrap(function): 28 @wrap(function) 29 def _wrap(*args,**kwargs): 30 LOG.info("运行位置 {}".format(param)) 31 return function(*args,**kwargs) 32 return _wrap 33 return wrap
②日志模块的调用方式如下
1 from Public.log import LOG,Logger 2 3 @logger("TestTcp") 4 class TestTcp(unittest.TestCase): 5 '''test_class''' 6 @classmethod 7 def setUpClass(cls):#类中最先执行 8 cls.tpc=TcpClientAPI() 9 cls.tpc.connect() 10 LOG.info("建立TCP连接") 11 12 @classmethod 13 def tearDownClass(cls): #类中最后执行 14 cls.tpc.close() 15 LOG.info("关闭TCP连接") 16 17 @ddt.data(*data_test) 18 def test_request_api(self,data_test): 19 self.doc=data_test['title'] 20 LOG.info("用例ID:{0} 命令:{1}".format(data_test['id'],data_test['command']))
执行完测试用例后,如何生成一份测试报告?
可以使用HTMLTestRunner.py,该文件是从网上下载的模板,可以直接使用
1 now=time.strftime("%Y%m%d%H",time.localtime(time.time())) 2 basedir=os.path.abspath(os.path.dirname(__file__)) 3 file_dir=os.path.join(basedir,'testReport') 4 file=os.path.join(file_dir,(now+'.html')) 5 fl_open=open(file,'wb') 6 runner=HTMLTestRunner(stream=fl_open,title='接口测试报告',description='测试结果') 7 runner.run(suite)
该测试报告可以显示执行tesecase成功了多少?失败了多少?哪一条成功,哪一条失败?以及查看每条testcase执行时产生的日志。
附录:
①数据驱动使用的excel测试用例格式如下:
②日志结果举例:
③测试报告结果举例:


浙公网安备 33010602011771号