我们做黑盒测试的同学,在没有自动化的条件下,遇到过这些烦恼:

  1. 辛辛苦苦构造了一波数据,测完一轮后,回归测试发现数据损坏
  2. 为了测通这条用例,需要一波猛操作调用多个依赖 API 做好场景
  3. 各种批量处理,比如给我这 100 个测试账户加 10 个亿资产
  4. ……

面对上述问题,初期咱们可以写好 DML 脚本、在 postman 录好依赖接口的用例等等,需要的时候「一键执行」。好吧,如果这些情况非常多,你要连接 n 个库、管理 n 个依赖接口的时候,事情就没那么「一键」了。

前面举例的场景简单的涉及了两类需求:调 API、跑数据库脚本。Python 的 pymysql、request 库就能够完成,可以说走到这一步已经比较省事了。如果能更进一步呢,咱们试试 Flask,分类把这些协助测试的操作封装成一个个 web 接口,让测试同学执行用例前回车一下 URL 就好。

Flask 作为 Python 轻量级的 web 应用程序框架,深受初入 web 开发和测试同学的喜爱,一个字「轻」!网上有很多讲解这里就不粘贴了。简单聊聊我们用它做了什么。

Flask 框架搭建

简单地理一下思路:

Flask 服务搭起来:

import logging, linecache, flask, json, os
from logging import getLogger
from logging.handlers import RotatingFileHandler
from flask import request, jsonify, Flask, render_template

server = flask.Flask(__name__, template_folder="testman", static_folder="testman")
log = getLogger(__name__)
current_dir = os.path.dirname(os.path.abspath(__file__))
#testhome前端页面资源
@server.route("/testman/")
def testman():
    return render_template("index.html")
#api_sce,api测试场景构造(api_scripts/env路径下),用例调用,必传参数:env-测试环境、pyname-脚本名称
@server.route('/testman/api_sce', methods=['get', 'post'])
def api_sce():
    pyname = request.values.get('pyname')
    env = request.values.get('env')
    py_path = current_dir + '\\api_scripts\\' + env + '\\'
    import sys
    sys.path.append(py_path)
    find = os.path.exists(py_path + pyname + '.py')
    if find == False:
        resu_err = {'code': 1, 'message': '没有找到模块: ' + pyname + '.py'}
        return jsonify(resu_err)
    else:
        try:
            import importlib
            py_model = __import__(pyname)
            importlib.reload(py_model)
            fun_ = getattr(py_model, pyname)
            data = fun_(env)
            print("返回的data:{}".format(data))
        except Exception as e:
            print(e)
            data = str(e)
        resu = {'code': 0, 'message': '执行模块:' + pyname + '.py' + ' 成功!', 'data': data}
        return jsonify(resu)

从简短的示例可以看到,这里一个 python 模块可以封装多个 API,你可以定义不同 API 来实现不同的测试工具,也可以大统一 1 个 API 去调用指定路径下的指定 python 模块。我们使用了后者,通过 Flask 接口的入参 pyname 找到对应的.py 处理模块并调用,好处在于(1)构建测试工具的同学不用关心框架,直接输出自己的.py 模块就好;(2)不用每次修改或新增工具时修改 Flask;

然后通过浏览器访问工具一键处理测试场景:
http://url/api_sce?env=env&pyname=pyname

嵌入 vue

欲求不满的测试同学应该会想进一步界面化工具,vue 搞起来:

** body **

<h2>选择环境</h2>
<el-radio @user3="api_showpy_run" label="sit" v-model="env">sit</el-radio>
<el-radio @user4="api_showpy_run" label="uat" v-model="env">uat</el-radio>
<el-radio @user5="api_showpy_run" label="dev" v-model="env">dev</el-radio>
<el-radio @user6="api_showpy_run" label="pet" v-model="env">pet</el-radio>           
<br>
<h2>选择脚本</h2>
<!-- 下拉框取pynames -->
<el-select v-model="selected" filterable aria-placeholder="请选择">
    <el-option 
     v-for="item in pynames"
     :label=item
     :value=item>
    </option>
</el-select>
<br>
<!-- 执行选中的python脚本,调用api_sce_run -->
<el-button type="primary" @user7="api_sce_run">执行</el-button>            <br>
<br>
执行结果:
<pre>{{result}}</pre>

** script **

methods:{
    // api_sce_run用于执行选中的脚本
    api_sce_run(){
        if (this.env == '') {
            this.$message({message:'请选择测试环境!',type:'warning'})
            // alert('请选择测试环境!')
            pass
        }
        if (this.selected == '') {
            this.$message({message:'请选择脚本!',type:'warning'})
            // alert('请选择脚本!')
            pass
        }
        this.$message({message:'提交成功,请耐心等待!',type:'success'});
        axios
            .get(this.url+'/api_sce?'+'env='+this.env+'&pyname='+this.selected)
            .then(response => (this.result = response.data))
    },
    // api_showpy_run用于查询当前环境路径下可执行的所有脚本文件,输出列表
    api_showpy_run(){
        this.selected = ''
        this.result = ''
        axios
            .get(this.url+'/api_showpy?'+'env='+this.env)
            .then(response => (this.pynames = response.data))
    },
}

** 界面 **

这样,我们可以减少在回归测试阶段场景构建的重复投入,非测试人员使用时也无需测试人员介入,比如产品走差、开发自测,可以直接界面操作生成测试场景。测试同学可以更专注于用例设计开发和测试执行。


↙↙↙阅读原文可查看相关链接,并与作者交流