草帽路飞UU 发表于 2019-4-11 13:59:49

接口测试框架(三)-框架优化

* 一、加入读取、写入Excel文件功能

第一步,在文件读取类中加入读取与写入excel文件的类。
from xlrd import open_workbook
from xlutils.copy import copy
from xlwt import Style

class ExcelReader():
    def __init__(self, excel_file, sheet, title_line=True):
      if os.path.exists(excel_file):
            self.excel_file = excel_file
      else:
            raise FileNotFoundError('File not found!%s')
      self.sheet = sheet
      self.title_line = title_line
      self.table = None
      self._data = list()

    def set_value(self,col, row, value):
      #   将传入值写进xlsw文件相应的行号,列号中
      rb = open_workbook(self.excel_file, formatting_info=True)
      wb = copy(rb)
      ws = wb.get_sheet(0)
      ws.write(col, row, value, Style.default_style)
      wb.save(self.excel_file)

    @property
    def data(self):
      #   读取xlsx文件
      if not self._data:
            work_book = open_workbook(self.excel_file)
            if type(self.sheet) not in :
                print 'Input <int> <str> please'
            elif type(self.sheet) is str:
                self.table = work_book.sheet_by_name(self.sheet)
            else:
                self.table = work_book.sheet_by_index(self.sheet)
            #   判断是否有标题,标题有无影响数据的格式(可运行最下方main函数进行比较)
            #   有标题:[{标题1:参数1,标题2:参数2,标题3:参数3}]
            #   无标题:[[参数1(行1),参数2(行1),参数3(行1)],[参数1(行2),参数2(行2),参数3(行2)]]
            if self.title_line:
                title = self.table.row_values(0)
                for row in range(1, self.table.nrows):
                  self._data.append(dict(zip(title, self.table.row_values(row))))
            else:
                for col in range(self.table.nrows):
                  self._data.append(self.table.row_values(col))
      return self._data
这里参照了灰蓝的写法,自己再加入了写入excel文件的方法。

* 二、创建测试类用于读取excel中的测试用例

这一步主要是讲落叶归根博客中的方法引入到我们的测试框架中。大致的思路是,将excel中的数据存入我们的用例类中,生成一个个的测试用例。好像就这一块算是我自己独立完成的,哎,要走的路好长呀。

这里有几个很重要的点,分别是:参数、关联、检查点、是否运行

参数:注意一定要是字典类型否则会出错。参数还要支持参数化,例如$token则会去配置文件中读取token的值,并赋值给该参数。

关联:这里还是拿token举例。比如说我先执行登录接口,登录成功后会返回给我们一个token,接下来的测试都需要用到token。那么我们在这里将登录接口中的token设为关联,运行登录测试用例后,就会将刚获取的token的值存入配置文件中。

检查点:这个比较简单,看响应内容中是否有包含该字符串。

是否运行:这里的值设为yes就会执行,没有的话就不会执行。
#!/usr/bin/env python
#coding=utf-8

from utils.file_reader import YamlReader
from utils.config import BASE_PATH
from utils.client import HTTPsClient
from utils.log import logger
import yaml
import json
import os


class InterfaceCase(object):
    #   接口测试对象,属性对应接口测试xlsx文件。方法有建立用例数据,运行用例数据
    def __init__(self, data):
      self.data = data
      self.no = int('%d' % data['No.'])
      self.apiName = data['API']
      self.testCase = data['TestCase']
      self.host = data['HOST']
      self.url = data['URL']
      self.requestMethod = data['RequestMethod']
      self.params = data['Params']
      self.relation = data['Relation']
      self.checkPoint = data['CheckPoint']
      self.active = data['Active']
      self.result = 'Na'
      self.response = None
      self.y = YamlReader(os.path.join(BASE_PATH, 'config', 'test.yaml'))
      self.get_config()

    def __str__(self):
      #   漂亮的输出测试用例的重要属性
      return 'No.' + str(self.no) + ' API:' + self.apiName + ' TestCase:' + self.testCase + \
          ' result:' + self.result

    def get_config(self):
      #   将参数中带有$的参数与配置文件中的参数匹配,并赋值
      #   例如:参数中有$token,则将配置文件中token的值付给token这个参数
      try:
            params = json.loads(self.params)
      except ValueError:
            logger.warn('No.%s Params input error!' % self.no)
            return
      data = self.y.data
      for i in params:
            if '

* 三、编写测试用例

都写好啦,终于可以编写接口测试用例了!11,和10列我用来存储执行用例的情况,一个是检查点是否成功,另一个是响应内容。
<div class="blockcode"><blockquote>#!/usr/bin/env python
#coding=utf-8

import unittest
import os
from utils.file_reader import ExcelReader
from utils.log import logger
from utils.config import Config, DATA_PATH
from utils.interface_case import InterfaceCase


class InterfaceTest001(unittest.TestCase):
    excel_path = os.path.join(DATA_PATH, Config().get('data')['interface_case_list'])
    e = ExcelReader(excel_path, 0, True)
    case_list = e.data

    def test_func(self):
      for i in self.case_list:
            #   运行用例前,将xlsx文件中执行结果以及用例执行情况还原
            self.e.set_value(int('%d' % i['No.']), 11, 'Na')
            self.e.set_value(int('%d' % i['No.']), 10, '')
            t = InterfaceCase(i)
            #   是否执行该条用例
            if t.active == 'yes':
                response = t.run()
                logger.info(t)
                #   将用例执行结果以及用例执行情况写入xlsx
                self.e.set_value(t.no, 10, response['msg'])
                self.e.set_value(t.no, 11, t.result)


if __name__ == '__main__':
    #   运行测试用例
    unittest.main()
事后一些小小的想法

虽然刚开始的时候觉得落叶归根这种excel存储测试用例的方法实在是太赞了,但是写完之后发现了很多的局限性。比如这样写,我就很难用灰蓝博客中介绍的生成html报告的方法,只能看自己输出的日志文件。

项目开始的时候,我想用这个框架做接口测试,但是发现这个测试框架根本就不够灵活。比如我要做一个登录次数上限的用例,我就不能用这个测试框架,必须要自己重新写测试类。

还有一个特别困扰的问题,师父希望接口测试的脚本更加的灵活。灵活到,我给别人发一个脚本,他F5就可以直接运行。而不是这个框架这样,需要其他的测试员去读懂这个框架。读懂之后还要配置这个框架需要的环境。

总的来说,动手编写这个框架还是很开心的,提升了自己编写python脚本的能力。 in params:
                try:
                  params = data
                except KeyError:
                  raise KeyError('No.%s Params "%s" not found!' % (self.no, i))
      self.params = params

    def run(self):
      #   运行用例,暂时只支持POST以及GET方法。client.py中可支持更多参数配置
      h = HTTPsClient(url=self.host+self.url, method=self.requestMethod)
      if self.requestMethod == 'POST':
            self.response = h.json_transform_dict(h.send(data=self.params))
      elif self.requestMethod == 'GET':
            self.response = h.json_transform_dict(h.send(params=self.params))
      else:
            raise KeyError('method "%s" not support!' % self.requestMethod)
      if self.checkPoint:
            try:
                params = self.checkPoint.split('=')
            except TypeError:
                logger.error('checkPoint input error!')
                raise TypeError('checkPoint input error : %s' % self.checkPoint)
            value = str(self.response])
            if value != params:
                self.result = 'Fail'
                logger.info('No.%s check point "%s" not found ' % (self.no, self.checkPoint))
                return self.response
            elif value == params:
                self.result = 'Pass'
      else:
            self.result = 'Pass'
      #   判断是否存在关联,如果有且格式正确则将执行后的参数写入配置文件
      #   例如:$token=token,则将response中的token值存入到配置文件中
      if self.relation:
            try:
                l = self.relation.split(',')
            except TypeError:
                logger.error('relation input error!')
                raise TypeError('relation input error : %s' % self.relation)
            for i in l:
                try:
                  params = i.split('=')
                except TypeError:
                  logger.error('relation input error!')
                  raise TypeError('relation input error : %s' % i)
                data = self.y.data
                #   response['data']根据项目不同可能略有差异
                #   此处防止response中想要获取的值为空,产生异常
                if self.response['data']] == None:return self.response
                try:
                  data] = self.response['data']].encode('utf-8')
                except AttributeError:
                  data] = self.response['data']]
                #   将变量写入yaml文件
                self.y.data = yaml.dump(data, default_flow_style=False)
      return self.response

* 三、编写测试用例

都写好啦,终于可以编写接口测试用例了!11,和10列我用来存储执行用例的情况,一个是检查点是否成功,另一个是响应内容。
[      DISCUZ_CODE_2      ]
事后一些小小的想法

虽然刚开始的时候觉得落叶归根这种excel存储测试用例的方法实在是太赞了,但是写完之后发现了很多的局限性。比如这样写,我就很难用灰蓝博客中介绍的生成html报告的方法,只能看自己输出的日志文件。

项目开始的时候,我想用这个框架做接口测试,但是发现这个测试框架根本就不够灵活。比如我要做一个登录次数上限的用例,我就不能用这个测试框架,必须要自己重新写测试类。

还有一个特别困扰的问题,师父希望接口测试的脚本更加的灵活。灵活到,我给别人发一个脚本,他F5就可以直接运行。而不是这个框架这样,需要其他的测试员去读懂这个框架。读懂之后还要配置这个框架需要的环境。

总的来说,动手编写这个框架还是很开心的,提升了自己编写python脚本的能力。

jkcxjsf 发表于 2020-4-23 00:31:21

发的是山东省地方
页: [1]
查看完整版本: 接口测试框架(三)-框架优化