前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >unittest批量组织依赖用例(一)

unittest批量组织依赖用例(一)

作者头像
软件测试君
发布2019-11-04 16:45:42
1.2K0
发布2019-11-04 16:45:42
举报
文章被收录于专栏:测试人生测试人生

关注测试君 | 会上瘾

对于接口自动化,设计上的难点有:如何保证测试脚本的可复用性,以及脚本正确性。个人认为脚本的正确性是基于脚本的可复用性而言的,因为只有可复用性高使用频率大,才会慢慢的发现并改进脚本中的问题。经常看到很多小伙伴写着线性的一次性脚本,一次写完,第二次换个接口又要重新组织代码,忽略组织代码花去的时间,那谁又能保证你新组织的代码的正确性呢? 总而言之,我们写脚本的目的是以测试脚本测试系统,而不是以系统来测试我们写的测试脚本呀~如果使用你的脚本出了问题,你第一时间想的是修复你的脚本,那么就本末倒置啦~

那么如何设计出一个可复用性高的测试脚本呢?嘻嘻嘻,那就要从接口依赖说起来,只有搞定了依赖接口,才可以为设计一个高可用的测试脚本打下基础~那就开始吧~

首先先设计一个测试依赖接口,流程如下~

我们使用flask 编写对应的简单测试接口:

代码语言:javascript
复制
from flask import Flask, request,jsonify
from flask_cors import *
import json
class Config(object):
    DEBUG = True
    JSON_AS_ASCII = False

app = Flask(__name__)
CORS(app, supports_credentials=True)
app.config.from_object(Config)

A=1
B=2
C=3
D=4

@app.route('/DepenceOne', methods=['GET'])
def DepenceOne():
    if request.method == "GET":
        return jsonify({'One': A})

@app.route('/DepenceTwo', methods=['POST'])
def DepenceTwo():
    if request.method == 'POST':
        data = request.get_data()
        json_data = json.loads(data.decode("utf-8"))
        return jsonify({'Two': B+int(eval(json_data)['One'])})

@app.route('/DepenceThr', methods=['GET'])
def DepenceThr():
    if request.method == "GET":
        return jsonify({'Thr': C})

@app.route('/DepenceFou', methods=['POST'])
def DepenceFou():
    if request.method == 'POST':
        data = request.get_data()
        json_data = json.loads(data.decode("utf-8"))
        return jsonify({'Fou': D+int(eval(json_data)['Thr'])})

@app.route('/DepenceFive', methods=['POST'])
def DepenceFive():
    if request.method == 'POST':
        data = request.get_data()
        json_data = json.loads(data.decode("utf-8"))
        if int(eval(json_data)['Two'])+int(eval(json_data)['Fou'])==10:
            return jsonify({'data':'success'})


if __name__ == '__main__':
    app.config['JSON_AS_ASCII'] = False
    app.run('0.0.0.0',port=9999,debug=True)

接下来我们来设计测试类,按照常理我们是不是要写五个测试方法按照接口流程来组织执行顺序?不不不,我们今天就换个方法吧~ 我们先写一个requests 方法,我们采用昨天讲过的添加类属性保存依赖值~ 点击查看原文哟~

代码语言:javascript
复制
def requestRun(url, data, method,save,depence):
    if depence:
        data = json.dumps(str(data)% tuple(getattr(Depence,str(i)) for i in depence))
    if method =='post':
        req = requests.post(url=url,data=data)
    else:
        req = requests.get(url=url, data=data)
    if save:
        setattr(Depence, save, eval(req.text)[save])

现在新建一个测试类,并将requests方法放入:

代码语言:javascript
复制
class Testcases(unittest.TestCase):

    def requestRun(self,url, data, method, save, depence):
        if depence:
            data = json.dumps(str(data) % tuple(getattr(Depence, str(i)) for i in depence))
        if method == 'post':
            req = requests.post(url=url, data=data)
        else:
            req = requests.get(url=url, data=data)
        if save:
            setattr(Depence, save, eval(req.text)[save])

是不是有人要问了,unittest用例不是要以test开头吗?哈哈哈,接着看,我们现在要用到python的语法糖啦~写一个装饰器,返回requestRun函数~你们是不是已经猜到了?嘻嘻~

代码语言:javascript
复制
 @staticmethod
    def getTestFunc(args):
        def func(self):
            self.requestRun(**args)
        return func

现在假设我们已经拿到了api的执行顺序,一个list(下次再将如何组织api的执行顺序,以及数据源模板设计)例如:

代码语言:javascript
复制
list_data=[{'url':'http://192.168.11.9:9999/DepenceOne','data':None,'method':'get','save':'One','depence':None},
            {'url':'http://192.168.11.9:9999/DepenceTwo','data':{'One':'%s'},'method':'post','save':'Two','depence':['One']},
            {'url':'http://192.168.11.9:9999/DepenceThr','data':None,'method':'get','save':'Thr','depence':None},
            {'url':'http://192.168.11.9:9999/DepenceFou','data':{'Thr':'%s'},'method':'post','save':'Fou','depence':['Thr']},
            {'url':'http://192.168.11.9:9999/DepenceFive','data':{'Two':'%s','Fou':'%s'},'method':'post','save':None,'depence':['Two','Fou']},
           ]

接下来,我们要把我们测试数据组成一个个独立的方法,setattr 让Testcases 拥有更多的方法属性。

代码语言:javascript
复制
def ProTestCases():
    for args in range(len(list_data)):
        setattr(Testcases, 'test_func_%s' % (args),Testcases.getTestFunc(list_data[args]))

总的代码如下,也就是执行测试类之前必须先把继承unittest的测试类添加属性~

代码语言:javascript
复制
import requests
import unittest
import json
from uniTest.depence import *

list_data=[{'url':'http://192.168.11.9:9999/DepenceOne','data':None,'method':'get','save':'One','depence':None},
            {'url':'http://192.168.11.9:9999/DepenceTwo','data':{'One':'%s'},'method':'post','save':'Two','depence':['One']},
            {'url':'http://192.168.11.9:9999/DepenceThr','data':None,'method':'get','save':'Thr','depence':None},
            {'url':'http://192.168.11.9:9999/DepenceFou','data':{'Thr':'%s'},'method':'post','save':'Fou','depence':['Thr']},
            {'url':'http://192.168.11.9:9999/DepenceFive','data':{'Two':'%s','Fou':'%s'},'method':'post','save':None,'depence':['Two','Fou']},
           ]

class Testcases(unittest.TestCase):

    def requestRun(self,url, data, method, save, depence):
        if depence:
            data = json.dumps(str(data) % tuple(getattr(Depence, str(i)) for i in depence))
        if method == 'post':
            req = requests.post(url=url, data=data)
        else:
            req = requests.get(url=url, data=data)
        if save:
            setattr(Depence, save, eval(req.text)[save])

    @staticmethod
    def getTestFunc(args):
        def func(self):
            self.requestRun(**args)
        return func

def ProTestCases():
    for args in range(len(list_data)):
        setattr(Testcases, 'test_func_%s' % (args),Testcases.getTestFunc(list_data[args]))

最后我们另起一个py,导入测试类,运行~ yeah 完美,全部通过~

代码语言:javascript
复制
ProTestCases()
suite = unittest.TestLoader().loadTestsFromTestCase(Testcases)
with open(report_file + r'\TestReport.html', 'wb') as f:  # 从配置文件中读取
    HTMLTestRunner(stream=f, title='Api Test', description='依赖Demo', tester='ayo').run(suite)

每日一练,这段代码会输出什么呢~可以评论哈哈哈

代码语言:javascript
复制
def foo():
    return [lambda x: i+x for i in range(4)]

print([x(3) for x in foo()])
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 软件测试君 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档