利用fitnesse实现api接口自动化测试

上午在园子里乱逛,看了不少小伙伴们分享的接口测试方面的知识,仔细想想,我做接口测试也有几个年头了,大家所叙述到的一些经验或多或少,我也曾遇到过,突然意识到知识的点滴积累是多么的重要,我记得我最早接触接口测试的时候,就是只在浏览器里人工测试单个接口的返回结果,后来用python的unittest自己写测试框架,和现在大多数小伙伴们的方法差不多,测试用例也是存放在excle表中,这对于单人测试来说都还ok,但是如果是多人协同测试时,问题就出来了,因为按目录存放在不同的excle表中的测试用例,维护起来比较麻烦,而且不便于多人查询或共同维护测试用例。所以之前的公司老大给我们推荐了一个工具——fitnesse,它是用wiki方式在界面上管理测试用例,驱动后台脚本进行测试,因为测试用例界面是个wiki地址,可以很方便的和大家一起协同工作,而且用例查询和维护起来都方便的多。

我在之前的公司用了将近一年这个工具,但是因为刚休完产假的自己工作状态非常不好,其实并没有在这方面很尽心,只到来了新公司后,才又一次重新学习使用起这个工具来,还是api接口测试,年前我从不同的角度分别写了几个不同的demo,虽然现在大多数用fitnesse的人都是用的slim引擎,但是因为java helloworld水平的我一直用的python,找不到合适的支持slim的python插件,所以还是用的fitnesse的fit引擎,用PyFIT支持起来。

对于api接口功能测试,我个人认为需要关注的有这几个方面:接口状态,响应时间,字段格式,返回数据,想起来之前面试阿里时,提到接口测试,他问了我很多http协议类的,具体问题记不清了,大概是几次握手交互那类的,额,不知道是不是关注点不同的缘故,他问得几个关于接口测试的问题我都没用过,其实到现在我还是有些疑惑的,不知道是他理解的接口测试和我理解的有偏差,不过也许是我涉猎的领域太窄,对于接口应该怎么充分测试我是比较怀疑了,也经常会在网上翻阅关于接口测试的文档,但是感觉收效甚微,嗯,对于未知领域的探索仍在继续,对于已知领域的小果子,拿出来和小伙伴一起分享下吧

所测接口:api接口,返回结果json格式

所用工具:fitnesse,fit引擎,python

第一种方式:

测试思想:在页面上初始化测试数据,将接口的返回结果按每个字段逐一填写期望结果,和接口的实际结果比较

测试数据准备:在界面上利用sql语句初始化测试数据,然后在测试用例页面included 该页面

测试用例:将json各个字段拆开填写到测试用例表格中,用ColumnFixture,测试用例格式如下

baseurl:接口基本不变的部分,这一部分可以在表格外参数化然后传值到表格里,account和password是接口的两个输入参数,带?标识的是要验证的结果,将json返回结果的每个字段都拆开填写在表格中。

后台脚本:

class LoginTest(ColumnFixture):
      _typeDict = {
        "description":"String",
        "BaseUrl":"String",
        "account":"String",
        "password":"String",
        "status":"Int",
        "retMsg":"String",
        "token":"String",
        "uClen":"Int",
        "uCuserId":"Int",
        "uCamount":"String",
        }

      def __init__(self):
          ColumnFixture.__init__(self)
          self.account=‘‘
          self.password=‘‘
          self.BaseUrl=‘‘
          self.jsonData=‘‘
          self.ret=‘‘
      def getRes(self):                          url=self.BaseUrl+"account="+self.account+"&password="+self.password
          tmp=res.fetch_res(url)
          result = json.loads(tmp)
          return result
      def retMsg(self):
          self.jsonData=self.getRes()
          self.ret=self.jsonData["ret"]
          result=str(self.jsonData["ret"])+self.jsonData["msg"]
          return result
      def status(self):
          url=self.BaseUrl+"account="+self.account+"&password="+self.password
          result=res.fetch_status(url)
          return result
      def token(self):
          result=‘‘
          if self.ret==1:
              result= self.jsonData["data"]["token"]
          return result
      def uClen(self):
          result=‘‘
          if self.ret==1:
              result=len(self.jsonData["data"]["userCapital"])
          return result
      def uCuserId(self):
          result=‘‘
          if self.ret==1:
              result=self.jsonData["data"]["userCapital"]["userId"]
          return result
      def uCamount(self):
          result=‘‘
          if self.ret==1:
              result=str(self.jsonData["data"]["userCapital"]["amount"])
          return result

优点:测试脚本结构简单,测试用例格式清晰,缺点:如果接口返回层级或字段较多时,不便于测试用例维护,需要初始化测试数据并清除增加的数据,部分动态字段(比如creattime)无法准确校验

第二种方式:

测试思想:在已有数据库基础上,无需每次添加测试数据,在测试脚本中根据需求用sql语句检索出对应字段的数据,作为期望结果,和接口的实际结果比较

测试数据:已有数据库基础上

测试用例:

测试脚本部分示例:

 def retMsg(self):
            if self.status==200:
                self.jsonData=self.getRes()
                isUserSql="SELECT * FROM hcm_user WHERE NAME LIKE \‘"+self.account+"\‘ AND PASSWORD LIKE \‘"+self.password+ "\‘AND TYPE=0"
                self.isUser=db.queryDb(isUserSql)
                self.ret=self.jsonData["ret"]
                result=str(self.jsonData["ret"])+self.jsonData["msg"]
                return result
            else:
                return ‘‘
        def securityStatusCheck(self):
            symbol="="
            list=[‘userId‘,‘userName‘,‘emailStatus‘,‘mobileStatus‘,‘realNameAuthStatus‘,‘autoTransfer‘,‘trusteeshipAccountStatus‘]
            dataJson=[]
            dataCase=[]
            if self.isUser:
                sql="SELECT a.id,a.`name`,IF(a.email!=‘‘,1,0),IF(a.`mobile`,1,0),b.`yeepay_account_status`,b.auto_transfer,b.`yeepay_account_status` FROM hcm_user a,hcm_user_auth b WHERE NAME LIKE ‘"+self.account+"‘ AND a.id=b.user_id"
                data=db.queryDb(sql)
                if data:
                    for i in range (0,len(list)):
                        dataCase.append(list[i]+symbol+str(data[0][i]))
            if self.ret==1:
                tmp=self.jsonData["data"]["securityStatus"]
                for i in range (0,len(list)):
                    dataJson.append(list[i]+symbol+str(tmp[list[i]]))
            result=Check(dataJson, dataCase)
            return result

测试结果:

突然发现给自己写优缺点好二啊,反正就是上面两种都没有满足老大们的要求,他们希望我能写一个通用的框架,让没有任何编码能力的人也能进行接口测试,即只需要前台编写测试用例,不用管后台脚本就能进行测试,于是乎有了下面第三种方式

第三种方式:

测试思想:满足老大们的要求,不用编写任何脚本即可进行接口测试

测试数据:固定初始化好的数据库

测试用例:

其中,firsturl是被依赖的登录接口,url是所测接口,blackLIst是希望过滤de返回字段的黑名单(比如ordeId,每次都是变化的,无法准确校验,添加到黑名单中即可不对其校验),data是期望结果,因为所测接口需要先登录然后保持session,才能返回正常结果,所以此处采用的是fit的Actionfixture

测试脚本示例:

from fit.Fixture import Fixture
import urllib2,cookielib,urllib
import module,json
import sys
reload(sys)
sys.setdefaultencoding(‘UTF-8‘)

class ActionTest(Fixture):
    _typeDict = {}

    def __init__(self):#初始化参数
        Fixture.__init__(self)
        self.__firstUrl  = ‘‘   #< Private attributes (Python convention).
        self.__url = ‘‘
        self.__parameter = ‘‘
        self.__blackList=‘‘
        self.__data=‘‘
        self.res=‘‘
        self.status=‘‘
        self.expectedList=‘‘
        self.actualList=‘‘
        self.test=‘‘

    _typeDict["firstUrl"] = "String"
    def firstUrl(self, s):
        self.__firstUrl = s
    _typeDict["url"] = "String"
    def url(self, s):
        self.__url = s
    _typeDict["parameter"] = "Dict"
    def parameter(self, s):
        self.__parameter = s
    _typeDict["blackList"] = "List"
    def blackList(self, s):
        self.__blackList = s
    _typeDict["data"] = "String"
    def data(self, s):
        self.__data = s
    _typeDict["do"] = "Default"      #< AUTO-DETECT: None = void

    def do(self):#访问接口并保存结果
        cookie=cookielib.CookieJar()
        opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
        try:
            req=opener.open(self.__firstUrl)
            self.status=req.code
        except urllib2.HTTPError, e:
            self.status= e.code
        if self.status==200:
            for cj in cookie:
                if cj.name==‘JSESSIONID‘:
                    session= cj.value
            req=urllib2.Request(self.__url)
            data=urllib.urlencode(self.__parameter)
            try:
                tmp = opener.open(req,data)
                self.status=tmp.code
            except urllib2.HTTPError, e:
                self.status=e.code
            if self.status==200:
                self.res= tmp.read()
            else:
                self.res=‘{"status":"no 200"}‘
        else:
            self.res=‘{"loginStatus":"no 200"}‘
    _typeDict["status"] = "Int"
    def status(self):
        return self.status
    _typeDict["expect"] = "String"
    def expect(self):#调用module函数比较测试结果
        self.expectedList=[]
        self.actualList=[]
        module.resultList(self.__blackList,self.__data, self.res, self.expectedList, self.actualList)#比较后将结果存放到输出数组中
        result=module.outPut(self.expectedList)
        #tmp=unicode(self.__data, ‘utf-8‘)
        #return str(self.actualList
        return result
    _typeDict["actual"] = "String"
    def actual(self):#调用module函数比较测试结果
        result=module.outPut(self.actualList)
        return result 

测试结果:

时间: 2024-10-26 19:51:59

利用fitnesse实现api接口自动化测试的相关文章

【php】利用新浪api接口与php获取远程数据的方法,获取IP地址,并获取相应的IP归属地

本文与<[Servlet]Javaweb中,利用新浪api接口,获取IP地址,并获取相应的IP归属地>(点击打开链接)为姊妹篇,只是后端编程语言换成了php. 做出同样的效果,打开页面,得到客户端的ip,并获取利用新浪api接口获取此ip的归属地. 可以看到,在IE6也是相当正常的. 目录结构如下,非常简单,同样就两个文件,其实如果你愿意,写成一个php文件也可以,但是显示层和逻辑业务层还是不混在一起为好吧? 唯一值得注意的是,这两个文件打死也不能一个叫ipGet.php,ipGet.html

itnesse实现api接口自动化测试学习

上午在园子里乱逛,看了不少小伙伴们分享的接口测试方面的知识,大家所叙述到的一些经验或多或少,我也曾遇到过,突然意识到知识的点滴积累是多么的重要,我记得我最早接触接口测试的时候,就是只在浏览器里人工测试单个接口的返回结果,后来用python的unittest自己写测试框架,和现在大多数小伙伴们的方法差不多,测试用例也是存放在excle表中,这对于单人测试来说都还ok,但是如果是多人协同测试时,问题就出来了,因为按目录存放在不同的excle表中的测试用例,维护起来比较麻烦,而且不便于多人查询或共同维

【Servlet】Javaweb中,利用新浪api接口,获取IP地址,并获取相应的IP归属地

这里之所以调用新浪api接口,主要是可以避免我们在本地存放一个ip归属地库, 同时,我们在本地要存放用户的ip,仅仅存放其ip就可以了,无须存放其归属地,节省一个字段. 如下图,写一个带有获取客户端IP地址的网页: 首先,在Eclipse的目录结构如下: 里面除了servlet的支持包之外,就一个.jsp与一个.java. 其中这里用到Servlet3.0,因此web.xml没有任何东西: <?xml version="1.0" encoding="UTF-8"

REST API 自动化测试 利器Rest Assured(API接口自动化测试框架体系)

现在,越来越多的 Web 应用转向了 RESTful 的架构,很多产品和应用暴露给用户的往往就是一组 REST API,这样有一个好处,用户可以根据需要,调用不同的 API,整合出自己的应用出来.从这个角度来讲,Web 开发的成本会越来越低,人们不必再维护自己的信息孤岛,而是使用 REST API 互联互通 那么,作为 REST API 的提供者,如何确保 API 的稳定性与正确性呢?全面系统的测试是必不可少的.Java 程序员常常借助于 JUnit 来测试自己的 REST API,不,应该这样

Python Api接口自动化测试框架 代码写用例

公司新来两个妹子一直吐槽这个接口测试用例用excel维护起来十分费脑费事,而且比较low(内心十分赞同但是不能推翻自己),妹子说excel本来就很麻烦的工具,于是偷偷的进行了二次改版. 变更内容如下: 1.代码结构 image.png 2.新增测试报告网页版和版本管理 3.新增用例代码化 一.封装一个获取用例的模块 image.png 用例的写法可以按照yml文件的写法,后缀的文件都可为.conf..config..ini.[]中的是测试用例场景,下面的参数内容对应接口用例参数. 简单介绍下py

利用百度地图API和群蚁算法,对TSP问题进行模拟与求解

前言 最近由于换了工作,期间也有反思和总结上家公司的得失,总觉得有什么事情当初可以完成或者完成得更好,其中TSP问题就是其中之一.当初在开发一个仓配系统的时候,有一个线路排程的需求,当时自己简单在纸上画了思路,发现求精确解算法复杂度是N!,所以去百度,发现了NPC问题的概念,但是一直以来都没有对这个问题好好研究过,最终只是选择了贪心算法这一求近似解的方案,正好这是我的第一篇博客,就拿这个“遗憾”开刀吧. 1.  利用百度地图API模拟TSP的各个城市点 1.1. 调用百度地图API解析经纬度 这

利用Metaweblog技术的API接口同步到多个博客网站(详细)

很早就有这个想法:自己有时候会用到多个博客,有些博客在一个网站上写完之后,要同步到其他博客网站,自己只能复制粘贴,感觉特别没意思,复制粘贴的麻木了.一直在想有哪些技术能实现一次写博,多站同步.最近网上搜了下,还真有这方面的资料,那就是用Metaweblog的API接口,这种特别像foxmail一样能把多个邮箱都集中在一起管理来收发邮件,Metaweblog能一次把写的博客同步到多个博客. 直接用Metaweblog来实现同步功能不太方便,幸好有了Windows live writer这个实现了M

利用swagger模块开发flask的api接口帮助文档

swagger官网称其为世界最流行的api工具.用过的都说好.我已经深有体会. 附上官网编辑页面.只需要拷贝相应的文件就可以实现效果 swagger在线编辑器 下面主要讲解一下在python的flask框架下,如何使用这款屌炸天的应用. 1.安装flasgger 项目地址https://github.com/rochacbruno/flasgger pip install flasgger 2.写一个简单的web例子. 以下是简写代码 #coding:utf8 import sys reload

利用api接口来实现web网页登陆

因为公司的所有链接数据库的都是用的api接口  最近做了一个用api接口登陆 function Login() { if (!Validate()) { return false; } var para = {}; para.action = "login_by_api"; para.login_name = $.trim($("#txtLoginName").val()); para.password = $.trim($("#txtPassword&q