51Testing软件测试论坛

标题: [分享] 自动化测试与持续集成方案--接口测试 [打印本页]

作者: 巴黎的灯光下    时间: 2017-6-29 15:45
标题: [分享] 自动化测试与持续集成方案--接口测试
有人在上一个帖子中问,为什么要把接口测试排在最前面。 原因很简单,接口是先行的,接口没做好,后面的编码工作受限,拿不到数据。
传统接口测试
不知道别人家的接口测试是怎么做的。这边是用postman这个google插件。测试人员按照接口开发人员的wiki,设计测试用例,然后post/get一下。查看返回json的状态或者字段。



弱点是不便于管理case和不方便统计结果,执行要一个一个手工去点,效率低下。接口测试自动化
我用python写了个脚本,将case写在excel里,然后读取excel来实现这个过程,并自动判断和统计结果,生成报告。
case这么设计的。



脚本这么写的:
  1. #encoding:utf-8

  2. import ConfigParser
  3. import os
  4. import xlrd
  5. import re
  6. import httplib
  7. import urllib
  8. from urlparse import urlparse
  9. import json
  10. import time
  11. import unittest
  12. import pdf

  13. currentdir=os.path.split(os.path.realpath(__file__))[0]
  14. class test_class():
  15.     def getexcel(self):
  16.         casefile=currentdir + '/case.xls'
  17.         if ((os.path.exists(casefile))==False):
  18.             print "当前路径下没有case.xls,请检查!"
  19.         data=xlrd.open_workbook(casefile)
  20.         table = data.sheet_by_name('login')
  21.         nrows = table.nrows #行数
  22.         ncols = table.ncols #列数
  23.     #colnames = table.row_values(1) #某一行数据
  24.         for rownum in range(1,nrows):
  25.             for col in range (3, ncols):
  26.                 value=table.cell(rownum,col).value
  27.                 if (col==3):
  28.                     method=value
  29.                 if (col==4):
  30.                     url=value
  31.         return table,nrows,ncols

  32.     def getexceldetail(self,table,row,ncols):
  33.         #rownum = table.row_values(row) #某一行数据

  34.         for col in range (0, ncols):
  35.             value=table.cell(row,col).value
  36.             if (col==0):
  37.                 caseid=value
  38.         print caseid
  39.             if (col==3):
  40.                 method=value
  41.         print method
  42.             if (col==4):
  43.                 url=value
  44.         return method,url,caseid

  45.     def httpget(self,url):
  46.         httpClient = None
  47.         conn = urlparse(url)
  48.         url=url.encode('utf-8')
  49.         try:
  50.             httpClient = httplib.HTTPConnection(conn.netloc, timeout=10)
  51.             httpClient.request('GET', url)

  52.         # response是HTTPResponse对象
  53.             response = httpClient.getresponse()
  54.             print response
  55.             d0=response.read()
  56.             d0=d0.decode('unicode_escape')
  57.         except Exception, e:
  58.             print e
  59.         finally:
  60.             if httpClient:
  61.                 httpClient.close()
  62.     return response.status,d0

  63.     def httppost(self,url):
  64.         httpClient = None
  65.         conn = urlparse(url)
  66.         url=url.encode('utf-8')
  67.         try:
  68.             header = {"Content-type": "application/x-www-form-urlencoded",
  69.                   "Accept": "text/plain"}

  70.             httpClient = httplib.HTTPConnection(conn.netloc, timeout=30)
  71.             httpClient.request("POST", url)
  72.             response1 = httpClient.getresponse()
  73.             d1=response1.read()
  74.             d1=d1.decode('unicode_escape')
  75.         except Exception, e:
  76.             print e
  77.         finally:
  78.             if httpClient:
  79.                 httpClient.close()
  80.         return response1.status,d1
复制代码



作者: 巴黎的灯光下    时间: 2017-6-29 15:46
代码太多了点,没写下。其实就是一个读excel,一个post,一个get的过程。
后面还有一个对json的解析过程。开始以为是一个字典就搞定了,后面发现有些{}里面嵌套了好几层。
最后用了个递归搞定。
  1. [code]
  2.     #! /usr/bin/env python
  3.     #coding=utf-8
  4.     import urllib2
  5.     import json


  6.     class readjson():
  7.     def read(self,obj,key):
  8.     collect = list()
  9.     for k in obj:
  10.     v = obj[k]

  11.     if isinstance(v,str) or isinstance(v,unicode):
  12.     if key== ' ':
  13.     collect.append({k:v})
  14.     else:
  15.     collect.append({str(key)+"."+k:v})
  16.     elif isinstance(v,int):
  17.     if key== ' ':
  18.     collect.append({k:v})
  19.     else:
  20.     collect.append({str(key)+"."+k:v})
  21.     elif isinstance(v,bool):
  22.     if key== ' ':
  23.     collect.append({k:v})
  24.     else:
  25.     collect.append({str(key)+"."+k:v})
  26.     elif isinstance(v,dict):
  27.     collect.extend(read(v,k))
  28.     elif isinstance(v,list):
  29.     collect.extend(readList(v,key))
  30.     return collect

  31.     def readList(self,obj,key):
  32.     collect = list()
  33.     for index,item in enumerate(obj):
  34.     for k in item:
  35.     v = item[k]
  36.     if isinstance(v,str) or isinstance(v,unicode):
  37.     collect.append({key+"["+str(index)+"]"+"."+k:v})
  38.     elif isinstance(v,int):
  39.     collect.append({key+"["+str(index)+"]"+"."+k:v})
  40.     elif isinstance(v,bool):
  41.     collect.append({key+"["+str(index)+"]"+"."+k:v})
  42.     elif isinstance(v,dict):
  43.     collect.extend(read(v,key+"["+str(index)+"]"))
  44.     elif isinstance(v,list):
  45.     collect.extend(readList(v,key+"["+str(index)+"]"))
  46.     return collect
  47.     #ojt=test_data1

  48.     #print read(ojt,' ')
复制代码


最后是结果:

是用python写图表,生成pdf.

    from reportlab.graphics.shapes import Drawing  
    from reportlab.graphics.charts.barcharts import VerticalBarChart  
    from urllib import urlopen   
    from reportlab.graphics.shapes import *   
    from reportlab.graphics.charts.lineplots import LinePlot   
    from reportlab.graphics.charts.textlabels import Label   
    from reportlab.graphics import renderPDF  
    class pdfreport():
        def createpdf(self,datas):
            drawing = Drawing(400, 200)
            #data = [(13, 5, 20),(14, 6, 21)]
            data=datas
            bc = VerticalBarChart()
            bc.x = 50
            bc.y = 50
            bc.height = 125
            bc.width = 300
            bc.data = data
            bc.strokeColor = colors.black
            bc.valueAxis.valueMin = 0
            bc.valueAxis.valueMax = 50
            bc.valueAxis.valueStep = 10
            bc.categoryAxis.labels.boxAnchor ='ne'
            bc.categoryAxis.labels.dx = 8
            bc.categoryAxis.labels.dy = -2
            bc.categoryAxis.labels.angle = 30
            bc.categoryAxis.categoryNames = ['Jan-99','Feb-99','Mar-99']
            #bc.categoryAxis.categoryNames =ytype
            drawing.add(bc)

            drawing.add(String(250,150,"ss", fontSize=14,fillColor=colors.red))
            #drawing.add(String(250,150,des, fontSize=14,fillColor=colors.red))
            renderPDF.drawToFile(drawing,'report1.pdf','API')
            #renderPDF.drawToFile(drawing,'APIReport.pdf','API')

    datas=[(0,20),(0,25)]
    f=pdfreport()
    f.createpdf(datas)
[/code]
接口自动化的持续集成

配置到jenkins上也很简单,这里就不过多描述。现在问题是,生成的报告是pdf。Jenkins里面不太好展现出来。弄成zip附件查看不方便。最后我写个脚本将其传到共享里面,或者写脚本用邮件发出来。后面写打包的时候会讲到的。
探讨

这些脚本,还有很多可以完善的地方。我也没有花太多的精力去完善,我的宗旨是花少的时间,搞出简单又好用的东西。
上次看到思寒的一篇文章,就是自动生成接口的测试用例,这样效率大大提高了。
作者: 悠悠小仙仙    时间: 2017-6-29 16:02
恩。很好的方式。
接口多的话,都可以套个框架巡检起来了,逻辑也可以做深一点。
可以试试requests这个库,比urllib好用太多;JSON response可以直接用JSON库转化成字典:)
作者: 巴黎的灯光下    时间: 2017-6-29 16:03
有空去瞅瞅。
作者: 无bug    时间: 2017-7-26 18:07
【上次看到思寒的一篇文章,就是自动生成接口的测试用例,这样效率大大提高了。】

求地址。。




欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2