ultraedit 运行的是试用模式_原来用Unittest框架写接口测试用例这么简单!

0 1

TestCase作用

是最小的测试单元,用于检查特定输入集合的特定返回值,可以用来创建新的测试用例。

0 2

编写测试用例规则

(1)创建一个测试类,必须继承unnittest模块的TestCase类

(2)创建一个测试方法,必须以"test"开头

(3)调用被测试类,传入初始化数据

(4)调用被测试方法,得到计算结果。用assertEqual断言是否与预期结果相同。

(5)调用unnitest的main执行测试用例

.:一条运行通过的测试用例F:一条运行失败的测试用例E:一条运行错误的测试用例s:一条运行跳过的测试用例

0 3

定义测试方法

以test 开头的方法就是一条测试用例。

(1)准备用例数据:用例的参数(datas)和预期结果(excepted)

(2)执行功能函数,获取实际结果:result = res['code']

(3)对比实际结果和预期结果:(excepted, result)【用例执行通没通过的评判标准:断言异常】

8642f7d18f454e332a8e0825394a1b8d.png

0 4

测试用例包含内容

(1)数据处理

读取excel数据

数据驱动:ddt方法

替换excel数据:header加token,可变数据替换(正则替换)

excel数据格式处理:比如str转json-->eval,编号str转为int

(2)错误写入日志

(3)执行结果和对比结果写入excel

(4)查询数据库结果

完整代码

import osimport unittestfrom library.ddt import ddt,data # ddt数据驱动from com.doexcel import DoExcel # 操作excel数据from com.contants import DATA_DIR # 测试用例模块所在目录from com.myconf import conf #读取配置文件from com.log import my_log # 日志处理对象from com.handle_data import Header,replace_data,TestData # 数据处理from com.handle_request import HandleRequest # http请求方法from com.mysql import MySql # 导入数据库excel_path = (DATA_DIR,"") # excel路径@ddtclass TestClassName():excel = DoExcel(excel_path, "sheetname")cases = excel.read_data # 读取excel数据http = HandleRequest # 创建http请求对象mysql = MySql # 创建数据库对象@classmethoddef setUpClass(cls):("---------------开始执行TestClassName类测试用例---------")def setUp(self):pass# 每条用例执行之前都会执行@data(*cases)def test_methodName(self,case):# -----------------------第一步:准备用例数据-------------------------------------# 用例方法参数# 请求urlurl = ('url_info', 'url_base')+ case["url"]# 请求方法method = case["method"]# 数据替换case['data'] = replace_data(case['data'])# excel中读的数据类型str转为jsondata = eval(case["data"])# 请求头headers = getattr(Header, 'headers')# 将token加到请求头中headers['Authorization'] = getattr(TestData, 'token')# 预期结果expected = eval(case['expected'])# 该用例在表单中所在行row = int(case['case_id']) + 1#-----------------------第二步:发送请求到接口,获取实际结果-------------------------------------result = (url = url,method = method,json = data,headers = headers).jsonTestResult = 'FAIL' # 测试对比结果:默认为失败try:(expected ['code'], result['code'])TestResult = 'PASS'("执行用例:{0}--->执行通过".format(case["title"])) # 将测试结果写入日志文件except Asserti as e:("执行用例:{0}--->未执行通过,出错位置为:{1}".format(case["title"], e)) # 将测试报错结果写入日志文件raise efinally:(row = row, column = 9,value = str(result)) # 回写执行结果(row = row,column = 9,value = TestResult) # 回写比对结果def tearDown(self):pass# 每条用例执行之后都会执行@classmethoddef tearDownClass(cls):("---------------结束执行TestClassName类测试用例---------")if __name__ == '__main__':

说明:

·配置文件涉及内容:

[url_info]url_base = urlcontent-type = application/json; charset=UTF-8[test_info]....

·ddt实现接口报告中按接口名显示用例(修改ddt中的mk_test_name)

def mk_test_name(name, value, index=0):"""Generate a new name for a test case.

It will take the original test name and append an ordinal index and astring representation of the value, and convert the result into a validpython identifier by replacing extraneous characters with ``_``.We avoid doing str(value) if dealing with non-trivial values.The problem is possible different names with different runs, e.g.different order of dictionary keys (see PYTHONHASHSEED) or dealingwith mock objects.Trivial scalar values are passed as is.A "trivial" value is a plain scalar, or a tuple or list consistingonly of trivial values."""# Add zeros before index to keep orderindex = "{0:0{1}}".format(index + 1, index_len)# 添加了对字典数据的处理if not is_trivial(value) and type(value) is not dict: #如果不符合value的要求,则直接返回用例名称_下标作为最终测试用例名字return "{0}_{1}".format(name, index)# 如果数据是字典,则获取字典当中的api_name对应的值,加到测试用例名称中if type(value) is dict: try:value = value["case_name"] #case_name作为value值except:return "{0}_{1}".format(name, index)try:value = str(value)except UnicodeEncodeError:# fallback for python2value = ('ascii', 'backslashreplace')test_name = "{0}_{1}_{2}".format(name, index, value)return re.sub(r'W|^(?=d)', '_', test_name)

·数据处理文件

import refrom com.myconf import confimport random# 请求头class Header:headers = {'X-Lemonban-Media-Type': ('Content-Type': ('url_info','Content-Type'),'Authorization': None}class TestData:"""专门用来保存一些替换的数据""" token = None

def replace_data(data): # 判断是否有需要替换的数据 while ("#(.+?)#", data): # .匹配任意字符,+重复一次或多次,?匹配0次或1次(变成非贪婪模式)匹配分组:在匹配的数据中提取数据 key = ("#(.+?)#", data).group(0) # 字典的键 value = ("#(.+?)#", data).group(1) # 字典的值 try: data = (key, ('test_info', value)) # 替换信息为中的值 except: data = (key,getattr(TestData,value)) # 如果满足条件,且配置文件中没有配置数据,则读取临时变量的值 return data

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值