askstar

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

 

为什么要学习接口自动化测试

①接口变动小,故保证了自动化测试代码的使用期限,有点一劳永逸的感觉

②避免重复劳动,减少人力、节省时间

 


因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测试用例格式如下:

②日志结果举例:

 

③测试报告结果举例:

 

posted on 2018-09-10 14:29  askstar  阅读(233)  评论(0)    收藏  举报