python自动化自动化测试平台开发:4.后端开发之用例的储存和查看

Posted new nm个对象

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python自动化自动化测试平台开发:4.后端开发之用例的储存和查看相关的知识,希望对你有一定的参考价值。

1.需求讲解

在这里插入图片描述
我们这个测试平台的主要功能有:上传储存用例,查看用例,运行用例,下载用例,上传测试报告等。

2.储存用例功能

2.1 创建用例表

(1)普通创建

第一步:创建app.py,用来启动一个flask服务

from flask import Flask
import conf
from flask_restful import Api,Resource

# 实例化一个Flask对象,用于启动flask服务
app = Flask(__name__)

# 添加配置文件
app.config.from_object(conf)

# 实例化flask_restful对象
api = Api(app)

# 设置用例储存视图函数
class TestCaseStoreView(Resource):
    def get(self):
        return '666'

api.add_resource(TestCaseStoreView, '/', endpoint='testcase_store')

if __name__ == "__main__":
    app.run(debug=True,host='127.0.0.1',port=5055)

第二步:创建conf.py文件,用于项目的配置文件

"""
flask项目的配置文件
"""

# 数据库连接配置
HOSTNAME = '192.168.1.104'
PORT = 3306
USERNAME = 'root'
PASSWORD = 'ouyi1994'
DATABASE = 'auto_test_frame'
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
SQLALCHEMY_TRACK_MODIFICATIONS = True

第三步:创建models.py文件,用于创建用例表

"""
使用flask_sqlalchemy模块声明数据库表
"""
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
from app import app

# 实例化一个SQLAlchemy对象,用于操作数据库
db = SQLAlchemy(app)

class TestCaseModel(db.Model):
    """
    用例表模型类
    """

    __tablename__ = 'testcase'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True) # id,主键
    name = db.Column(db.String(30), unique=True, nullable=False) # 用例名
    description = db.Column(db.String(200), unique=False, nullable=True) # 描述
    file_path = db.Column(db.String(200), unique=True, nullable=False) # 用例文件路径
    update_time = db.Column(db.DateTime, default=datetime.now()) # 更新时间

if __name__ == "__main__":
    db.create_all()

(2)优化db和数据库表初始化

db是SQLAlchemy的一个实例化对象,用于操作数据库。所以我们在项目中会经常将db对象导入到其他文件中操作。为了防止导入db时,因为循环导入报错。我们可以将db对象放置在一个单独的第三方文件中存放。

第一步:新建一个exit.py文件,用于生成db对象。

"""
中间文件
"""

from flask_sqlalchemy import SQLAlchemy

# 实例化一个SQLAlchemy对象,用于操作数据库
db = SQLAlchemy()

使用该文件可以有效防止引用冲突

第二步:创建app.py,用来启动一个flask服务

from flask import Flask
import conf
from flask_restful import Api,Resource
from exit import db

# 实例化一个Flask对象,用于启动flask服务
app = Flask(__name__)

# 添加配置文件
app.config.from_object(conf)

# 实例化flask_restful对象
api = Api(app)

# 将SQLAlchemy对象db关联到app
db.init_app(app)


# 设置用例储存视图函数
class TestCaseStoreView(Resource):
    def get(self):
        return '666'


api.add_resource(TestCaseStoreView, '/', endpoint='testcase_store')

if __name__ == "__main__":
    app.run(debug=True,host='127.0.0.1',port=5055)

第三步:创建models.py文件,用于创建用例表

"""
使用flask_sqlalchemy模块声明数据库表
"""
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
from exit import db

class TestCaseModel(db.Model):
    """
    用例表模型类
    """

    __tablename__ = 'testcase'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(30), unique=True, nullable=False)
    description = db.Column(db.String(200), unique=False, nullable=True)
    file_path = db.Column(db.String(200), unique=True, nullable=False)
    update_time = db.Column(db.DateTime, default=datetime.now())

使用Flask_Migrate和flask_script来完成数据库的初始化和迁移

因为我们在项目开发中会频繁的改动数据库类结构,使用Flask_Migrate和flask_script可以非常方便的来完成数据库的初始化和迁移管理。所有的迁移操作其实都是Alembic做的,能跟踪模型的变化,并将变化映射到数据库中。
创建manage.py文件,用来完成数据库的管理。

"""
用于数据库初始化
"""

from flask_script import Manager
from flask_migrate import Migrate,MigrateCommand
from exit import db
from app import app
from models import TestCaseModel # 将需要初始化或者迁移的表模型类导入到该文件中

manage = Manager(app)

Migrate(app,db)

manage.add_command('db',MigrateCommand)

if __name__ == '__main__':
    manage.run()
  • 在命令行执行python manage.py db init生成数据表初始化的迁移文件migrates
    在这里插入图片描述
  • 在命令行执行python manage.py db migrate,自动检测模型,生成迁移脚本。
  • 在命令行python manage.py db upgrade,将迁移脚本的操作映射到数据库中。

2.2 实现储存用例的功能

(1)接口定义

在这里插入图片描述

(2)普通方式实现接口

编辑app.py文件

import os
from datetime import datetime

from flask import Flask, request
import conf
from flask_restful import Api, Resource
from exit import db
from models import TestCaseModel

# 实例化一个Flask对象,用于启动flask服务
app = Flask(__name__)

# 添加配置文件
app.config.from_object(conf)

# 实例化flask_restful对象
api = Api(app)

# 将SQLAlchemy对象db关联到app
db.init_app(app)


# 设置用例储存视图函数
class TestCaseStoreView(Resource):
    def post(self):
        name = request.form.get('name') # 获取请求参数:name
        description = request.form.get('description') # 获取请求参数:description
        test_file = request.files.get('test_file') # 获取请求参数:test_file
        test_file_name = test_file.filename # 用例文件名。

        # 判断name参数是否符合规定
        if name is not None and isinstance(name,str):

            # 判断test_file参数是否符合规定
            if test_file is not None and test_file_name.endswith('.py'):

                # 判断description参数是否为空
                if description is not None:

                    # 判断判断description参数是否为str类型
                    if isinstance(description,str):
                        now = datetime.now().strftime('%Y-%m-%d-%H%M%S')  # 生成时间戳
                        now_path = os.getcwd()  # 获取当前目录路径
                        test_file.save(f'./{now}_{test_file_name}')  # 保存用例文件到当前目录路径
                        file_path = os.path.join(now_path, f'{now}_{test_file_name}')  # 拼接出用例文件路径
                        testcase = TestCaseModel(name=name, file_path=file_path,description=description)
                        # 保存到数据库
                        db.session.add(testcase)
                        db.session.commit()
                        return jsonify({
                            'code': 200,
                            'message': 'success'
                        })
                    else:
                        return jsonify({
                            'code': 404,
                            'message': 'description必须为str类型'
                        })

                else:
                    now = datetime.now().strftime('%Y-%m-%d-%H%M%S') # 生成时间戳
                    now_path = os.getcwd() # 获取当前目录路径
                    test_file.save(f'./{now}_{test_file_name}') # 保存用例文件到当前目录路径
                    file_path = os.path.join(now_path,f'{now}_{test_file_name}') # 拼接出用例文件路径
                    testcase = TestCaseModel(name=name,file_path=file_path)
                    # 保存到数据库
                    db.session.add(testcase)
                    db.session.commit()
                    return jsonify({
                        'code':200,
                        'message':'success'
                    })

            else:
                return jsonify({
                    'code': 404,
                    'message': 'test_file参数不能为空,且必须为python文件'
                })
        else:
            return jsonify({
                'code':404,
                'message':'name参数不能为空,且必须为str类型'
            })





api.add_resource(TestCaseStoreView, '/testcase_store/', endpoint='testcase_store')

if __name__ == "__main__":
    app.run(debug=True,host='127.0.0.1',port=5055)

我们使用postman来构造数据访问接口,看接口功能是否实现。
在这里插入图片描述

结果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(3)优化请求参数校验

  • 在上面的接口实现中,我们需要使用了if语句来校验前端传过来的参数。这种方式是不可取的,因为会使得我们的代码是否冗余。我们可以看到这个接口中只有3个参数,确使用了大量的if语句来进行校验。

  • 我们可以使用flask-wtf来校验前端参数。

新建一个form.py文件,来进行参数的校验工作。

from wtforms import Form, StringField, FileField
from wtforms.validators import Length, InputRequired, ValidationError
from flask_wtf.file import FileRequired


# 校验用例储存请求参数
class TestCaseForm(Form):
    name = StringField(validators=[Length(max=30, message='参数name不合法,参数长度不能大于30'),
                                   InputRequired(message='参数name不能为空')
                                   ])
    description = StringField(validators=[Length(max=200, message='参数description不合法,参数长度不能大于200')])
    test_file = FileField(validators=[FileRequired(message='必须上传用例文件')])

    def validate_test_file(self, field):
        """自定义test_file验证器"""
        if not field.data.filename.endswith('.py'): # field.data获取需要校验的参数值,这里为上传的文件对象
            raise ValidationError('用例文件必须为python文件') # 使用ValidationError抛出提示信息

修改app.py文件:

import os
from datetime import datetime
from flask import Flask, request, jsonify
import conf
from flask_restful import Api, Resource
from exit import db
from forms import TestCaseForm, GetTestCaseForm
from models import TestCaseModel
from werkzeug.datastructures import CombinedMultiDict


# 实例化一个Flask对象,用于启动flask服务
app = Flask(__name__)

# 添加配置文件
app.config.from_object(conf)

# 实例化flask_restful对象
api = Api(app)

# 将SQLAlchemy对象db关联到app
db.init_app(app)


# 设置用例储存视图函数
class TestCaseStoreView(Resource):
    def post(self):

        now = datetime.now().strftime('%Y-%m-%d-%H%M%S')  # 生成时间戳
        now_path = os.getcwd()  # 获取当前目录路径

        # 实例化TestCaseForm对象,用于参数校验。其参数为需要校验的参数字典列表
        # CombinedMultiDict将两个属性组合起来传给校验器
        form = TestCaseForm(CombinedMultiDict([request.form,request.files]))


        if form.validate():

            # 参数校验通过
            name = form.name.data # 获取参数name的值
            description = form.description.data # 获取参数description的值
            test_file = form.test_file.data # 获取用例文件test_file对象

            # 判断name是否已在数据库中存在
            name_fag = db.session.query(TestCaseModel).filter(TestCaseModel.name==name).first()
            if name_fag is  None:
                if description is  not None:
                    # 保存用例文件
                    file_path = os.path.join(now_path, f'./case_files/{now}_{test_file.filename}')
                    test_file.save(file_path)

                    # 保存数据库
                    testcase = TestCaseModel(name=name,description=description,file_path=file_path)
                    db.session.add(testcase)
                    db.session.commit()

                    res = {
                        'code': 200,
                        'message': 'success'
                    }
                    return jsonify(res)
                else:
                    # 保存用例文件
                    file_path = os.path.join(now_path, f'./case_files/{now}_{test_file.filename}')
                    test_file.save(file_path)

                    # 保存数据库
                    testcase = TestCaseModel(name=name, file_path=file_path)
                    db.session.add(testcase)
                    db.session.commit()

                    res = {
                        'code': 200,
                        'message': 'success'
                    }
                    return jsonify(res)
            else:
                res = {
                    'code': 404,
                    'message': '用例名字不能重复'
                }
                return jsonify(res)

        else:
            # 参数校验不通过
            res = {
                'code': 404,
                'message': form.errors
            }
            return jsonify(res)

api.add_resource(TestCaseStoreView, '/testcase_store/', endpoint='testcase_store')

if __name__ == "__main__":
    app.run(debug=True,host='127.0.0.1',port=5055)

运行结果如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.查询用例功能

3.1 接口分析

在这里插入图片描述

3.2 实现接口

修改form.py文件

from wtforms import Form, StringField, FileField, IntegerField
from wtforms.validators import Length, InputRequired, ValidationError
from flask_wtf.file import FileRequired


# 校验用例储存请求参数
class TestCaseForm(Form):
    name = StringField(validators=[Length(max=30, message='用例名字不合法,参数长度不能大于30'),
                                   InputRequired(message='用例名字不能为空')
                                   ])
    description = StringField(validators=[Length(max=200, message='用例描述不合法,参数长度不能大于200')])
    test_file = FileField(validators=[FileRequired(message='必须上传用例文件')])

    def validate_test_file(self, field):
        """自定义test_file验证器"""
        if not field.data.filename.endswith('.py'): # field.data获取需要校验的参数值,这里为上传的文件对象
            raise ValidationError('用例文件必须为python文件') # 使用ValidationError抛出提示信息

class GetTestCaseForm(Form):
    id = IntegerField(validators=[InputRequired('用例id不能为空')])


修改app.py

import os
from datetime import datetime
from flask import Flask, request, jsonify
import conf
from flask_restful import Api, Resource
from exit import db
from forms import TestCaseForm, GetTestCaseForm
from models import TestCaseModel
from werkzeug.datastructures import CombinedMultiDict


# 实例化一个Flask对象,用于启动flask服务
app = Flask(__name__)

# 添加配置文件
app.config.from_object(conf)

# 实例化flask_restful对象
api = Api(app)

# 将SQLAlchemy对象db关联到app
db.init_app(app)


# 设置用例储存视图函数
class TestCaseStoreView(Resource):
    def post(self):

        now = datetime.now().strftime('%Y-%m-%d-%H%M%S')  # 生成时间戳
        now_path = os.getcwdpython自动化自动化测试平台开发:5.后端开发之用例文件下载,执行用例,查询用例执行状态

python自动化自动化测试平台开发:2.flask技术讲解上

python自动化自动化测试平台开发:3.flask技术讲解上

自动化测试平台:前期准备和后端服务搭建

十年测试经验的阿里p10讲解python初阶:基础语法 python全栈自动化测试系类4-1

python Django接口自动化测试