接口自动化测试方案详解

文章目录[隐藏]

前言

去年,我们进行了项目的拆分,拆分后的各个子系统也都逐步的改成了通过接口进行数据的交换,接口测试也被提上日程。经过一段时间的探索,接口自动化测试方案越来越完善,今天给大家做个详细的讲解。

方案

目前我们的接口都是使用的http协议,其测试的基本原理是模拟前端(客户端)向服务器发送数据,得到相应的响应数据,从而判断接口是否可以正常的进行数据交换。在测试的过程中尝试过两种方式,一种是利用性能测试工具Jmeter模拟客户端发起http请求,另外一种是使用python脚本直接编写脚本模拟客户端发起http请求。

利用Jmeter工具配置,需要对如何利用Jmeter进行性能测试熟悉,通过相应的配置可完成,但不够灵活,比如某些字段需要经过特定的加密处理,不能通过Jmeter直接完成。

所以选择直接用python脚本进行,模拟http请求也就几行代码就可完成。但只是模拟请求不是最终的目标,也需要易用,不会编码的人也会维护我们的测试用例,所以形成了现在的形态,遵循了测试框架的一些基本原则,业务逻辑与测试脚本分离,测试脚本与测试数据分离。大致框架如下图所示:

image001

目录结构如下:

image002

所有的测试用例使用Excel统一管理,测试数据根据需要可以选择配置在Excel中或者保存在测试数据文件中。测试用例格式如下:

image003 image006 image007

日志格式如下:

image010

测试完成后可将异常的接口通过邮件发送给相关人。以上是接口测试方案的大致介绍,下面给大家说说具体怎么配置用例。

如何进行测试

测试的核心脚本已经搭建好,后续不会有太大的改动,维护测试用例的Excel表格即可完成后续接口的测试,不管是新接口的测试还是老接口的回归,那如何编写一个接口的测试用例呢?

1、      打开测试用例的Excel表格,填写用例编号、接口描述信息,被测接口的域名和请求地址。

image011

2、      选择接口请求的方式,目前有两种,一种是POST,一种是GET,根据实际情况选择。

image013

3、      选择接口接收数据的方式,目前有三种,Form类型,请求的数据会进行urlencode编码,一般都是这种类型,官网的接口主要是这种;Data类型,以文本的形式直接请求接口,不经过urlencode编码,引擎的接口大部分是这种,选择Data类型时,请求的数据有两种,一种是直接在Excel中配置json字符串,一种是填写文本文件路径,文件中也是json字符串,主要在于post的数据很大时,比如保存案例,在Excel中不好管理。File类型表示上传文件,在测试上传时选择File类型。

image014

4、      配置需要向接口发送的数据,如下图所示,需要根据上一步中选择的类型配置正确的测试数据,除了填写的是文件路径外,数据必须是标准的json格式字符串。

image015

测试数据中,可以带参数,格式为{parameter},此处的参数必须在后面的关联(Correlation)字段中有赋值,在后面的关联字段配置给大家详细介绍。其中内置了四个参数,分别是:{randomEmail}(随机邮箱地址)、{randomTel}(随机手机号码)、{timestamp}(当前时间戳)、{session}(session id,默认为None)以及{hashPassword}(hash加密密码,明文123456)。

5、      配置数据是否需要编码加密,目前有三种,不加密,MD5加密和DES加密。这是根据我们自身项目的特点加的选项,引擎有几个接口需要进行MD5加密,场景秀的接口都经过了DES加密。

image016

6、      配置检查点,检查点的目的是校验接口返回的数据是否是我们期望的。

image017

7、      配置关联,在接口的测试过程中,两个接口常常会有相关性,比如引擎新建案例需要先登录官网,那么,就需要做前后接口数据的关联。前面步骤已经提到过,在配置测试数据的时候可以配置参数,那么,关联的配置就是为了给这些参数赋值的,格式如下:${parameter}=[level1][level2][level3],多个参数中间用半角的分号(;)隔开,如下图所示。关联参数有两部分组成,等号前面是参数名称,需要跟测试数据中配置的参数名称保持一致,等号后面的部分是获取当前接口返回值的,因为接口返回值都是json格式的字符串,所以[level1]表示第一层级的指定key的值,[level1][level2]表示获取第一层级指定key的值中的指定key的值,有点绕,我们举例说明,大家就明白了。

image018

登录接口的返回值是:

{"data":"http:\/\/my.test.liveapp.com.cn\/admin\/myapp\/applist","success":true,"message":"6tdehonrs6mg9metjqprfind16"}

后续的操作都需要是登录状态,所以需要得到session id,那么参数就可以这么写:${session}=[message],得到的值就是6tdehonrs6mg9metjqprfind16。

保存案例接口的返回值是:

{"ecode":0,"msg":"SUCCESS","data":[{"$id":"55d43d077f8b9ad56b8b4576","page_id":115323,"page_order":0},……

后续的操作需要mongo id和page id,那么参数可以这样写:{mongo_id}=[data][0][id];${page_id}=[data][0][page_id],就可以分别得到55d43d077f8b9ad56b8b4576和115323。这里大家发现会出现数字,是因为”data”的值是一个列表,而不是字典,没有相应的key,所以可以用数字代替,从0开始计算。

8、      最后一步,配置用例是否执行,只有Yes和No两种选项,这个很好理解,就不多解释了。

image019

以上就是配置一条用例的过程,配置完成后,保存Excel文件,提交到SVN即可,Jenkins接口测试的项目已经配置好,在每次引擎项目构建之后都会自动构建接口测试项目。

如果大家还有什么疑问,可以找我一起探讨。

附代码如下(Github:https://github.com/TronGeek/InterfaceTest):

接口自动化定期扫描,共有 ' + str(len(errorTest)) + ' 个异常接口,列表如下:' + ''
        for test in errorTest:
            html = html + ''
        html = html + '
接口状态接口地址接口返回值
' + test[0] + '' + test[1] + '' + test[2] + '' + test[3] + '
' #sendMail(html) if __name__ == '__main__': main()

“接口自动化测试方案详解”的49个回复

  1. 统一回复:
    这是几年前的实验项目,现不推荐此方法,参考这个原型搭建了一个接口测试平台,https://www.bstester.com/2016/10/way-to-test-interfaces-interface-test-platform-another,大家可参考这个思路进行接口测试。

  2. 请教一下,登录接口的response里有个token,后面的接口请求时,headers里需要用到这token,如何操作?谢谢!

  3. 你好 麻烦问下你这个runTest方法的局部变量 为啥可以给InterfaceTest用啊,作用域不一样啊 为啥能取到呢

  4. 这个是直接用脚本显示的报错,求解答一下,谢谢!!!
    [2018-08-21 15:52:33,935] [ERROR] 1 添加屏蔽词 失败!!!, [ 400 ], b’\n 400 Bad Request\n \n

    400 Bad Request

    \n

    \xe2\x9d\xa4\n \n ‘

  5. [ERROR] 1 首页 失败!!!, [ 301 ], b’\r\n\r\n301 Moved Permanent
    ly\r\n\r\n

    301 Moved Permanently

    \r\
    n

    The requested resource has been assigned a new permanent URI.

    \r\n

    Po
    wered by Tengine\r\n\r\n’

    一直提示重定向,不知道有没有人遇到过这个问题,怎么解决呢?

  6. try:
    import xlrd
    except:
    os.system(‘pip install -U xlrd’)
    import xlrd

    楼主,请问你为啥还要这么写呢?是为了防止没有这个库吗?所以才用try..except来捕捉异常吗?为啥会针对这个库而进行捕捉呢?不是一般导入这个库的话,就能用这个库吗?

  7. 为什么我填的file类型,request——data填的文件路径,执行时找不到

  8. 一直爆这个错误。不知道是什么意思??

    Traceback (most recent call last):
    File “D:/python/jiekou/InterfaceTest-master/LiveApp.py”, line 255, in
    main()
    File “D:/python/jiekou/InterfaceTest-master/LiveApp.py”, line 246, in main
    errorTest = runTest(‘TestCase/TestCase.xlsx’)
    File “D:/python/jiekou/InterfaceTest-master/LiveApp.py”, line 126, in runTest
    status,resp = interfaceTest(num,api_purpose,api_host,request_url,request_data,check_point,request_method,request_data_type,correlationDict[‘${session}’])
    File “D:/python/jiekou/InterfaceTest-master/LiveApp.py”, line 165, in interfaceTest
    conn.request(‘POST’,request_url,request_data,headers=headers)
    File “C:\Users\wang\AppData\Local\Programs\Python\Python36\lib\http\client.py”, line 1239, in request
    self._send_request(method, url, body, headers, encode_chunked)
    File “C:\Users\wang\AppData\Local\Programs\Python\Python36\lib\http\client.py”, line 1285, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
    File “C:\Users\wang\AppData\Local\Programs\Python\Python36\lib\http\client.py”, line 1234, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
    File “C:\Users\wang\AppData\Local\Programs\Python\Python36\lib\http\client.py”, line 1026, in _send_output
    self.send(msg)
    File “C:\Users\wang\AppData\Local\Programs\Python\Python36\lib\http\client.py”, line 964, in send
    self.connect()
    File “C:\Users\wang\AppData\Local\Programs\Python\Python36\lib\http\client.py”, line 936, in connect
    (self.host,self.port), self.timeout, self.source_address)
    File “C:\Users\wang\AppData\Local\Programs\Python\Python36\lib\socket.py”, line 704, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
    File “C:\Users\wang\AppData\Local\Programs\Python\Python36\lib\socket.py”, line 745, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
    socket.gaierror: [Errno 11004] getaddrinfo failed

    1. 这个貌似是和邮件模块相关的,你可以把邮件的相关代码注释掉,试一下。

  9. 请问下 代码哪一段提到 可以提取接口的返回值?貌似没看到

  10. 写的很好,关注了公众号,向你学习。不过缺少了TestCasePro.xlsx文件,我这边没有调通。

  11. 我现在的接口请求基本都是GET 我只是想断言返回的数据是否对不对。但是有个问题就是,我返回的数据都是DES加密过的。

  12. 接口是form表单形式Post的,有字段,也有文件,单纯使用file或form类型就不行了,是这样吗?

  13. 无法运行,一直在提取请求数据的时候报编码错误,这个怎么解决?

      1. 我用的py3.4,运行报Error: Can’t convert ‘bytes’ object to str implicitly

  14. 目前我只调通了一个get请求的接口,这个接口是没有加密的,post请求的是加密的,一直都是失败。

  15. Traceback (most recent call last):
    File “D:InterfaceTest-masterLiveApp.py”, line 33, in
    logging.basicConfig(format=log_format,filename=log_file,filemode=’w’,level=logging.DEBUG)
    File “C:Users55AppDataLocalProgramsPythonPython35liblogging__init__.py”, line 1744, in basicConfig
    h = FileHandler(filename, mode)
    File “C:Users55AppDataLocalProgramsPythonPython35liblogging__init__.py”, line 1008, in __init__
    StreamHandler.__init__(self, self._open())
    File “C:Users55AppDataLocalProgramsPythonPython35liblogging__init__.py”, line 1037, in _open
    return open(self.baseFilename, self.mode, encoding=self.encoding)
    FileNotFoundError: [Errno 2] No such file or directory: ‘D:\InterfaceTest-master\log\liveappapi.log’
    >>>

  16. 有一点我不明白,request_data若是选择为空的情况下就直接填{}就可以了么?我在运行的时候发现有问题诶~

    1. 具体什么问题呢?其实请求数据还得按项目实际情况调整,一般没有请求数据,可以填写空json字符串,Request_Data_Type选择Data时,可以直接留空。

  17. 很不错,我最近参考了做了一下,我在请求接口的时候get请求返回的并不是json格式的字符串,所以需要在源代码上进行调整;另外现在做的需要跨平台进行监控,所以对于请求头的需要分别配置,对代码调整了一下用起来了[兔子]

评论已关闭。