python flask mock服务(开箱即用,含数据库相关代码)

技术简介

mock技术又叫测试桩、挡板

在软件测试中,对于一些不容易构造、获取的对象,用一个虚拟的对象来代替它,以达到相同的效果,这个虚拟的对象就是mock。

mock技术并不是只有测试领域用,最早是在开发领域应用,典型例子:前后端联调。比如一个功能,前端功能写完了,但是后端还没做好,前端可以使用mock技术模拟后端发过来的数据,查看效果。

测试行业中的应用场景

1.某个新需求,开发未完成,测试人员使用mock技术,把新增的业务使用mock技术模拟出来,进行初步测试,等开发人员开发完成,再进行真实环境测试。

2.在项目中,经常会用到很多第三方接口,比如充值、防沉迷验证。第三方接口返回效率低、环境搭建麻烦,可以使用mock技术,先测试整体流程。

怎么用mock?

1.测试团队开发–技术要求高,使用django、flask等

2.使用现成工具 postman、fiddler等

3.不写代码,使用框架(moco)去创建mock moco.jar+xxx.json (简单)

mock服务

实现mock的技术有很多,这些技术中,可以分为两类–mock数据和mock服务。

mock数据:即mock一个对象,写入一些想要的数据,通过它进行自己想要的测试,常用的有:EasyMock、WireMock等,多用于单元测试。

mock服务:即mock一个sever,构造一个依赖服务并给予他预期的服务返回值,适用范围广,更加适合集成测试。

主程序-app.py文件

from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, Text, DateTime
from datetime import datetime
import os
import json
app = Flask(__name__)
# 配置 MySQL 数据库连接
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:rootroot@127.0.0.1/mock'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 初始化数据库对象
db = SQLAlchemy(app)
# 定义数据模型
class MockData(db.Model):
    __tablename__ = 'mockdata'
    id = Column(Integer, primary_key=True)
    interface_name = Column(Text, nullable=False)
    input_data = Column(Text, nullable=False)
    output_data = Column(Text, nullable=False)
    timestamp = Column(DateTime, default=datetime.utcnow)
    def __repr__(self):
        return f''
# 创建新的路由来预先填充数据
@app.route('/mock/prepopulate', methods=['POST'])
def prepopulate_mock_data():
    # 从请求中获取数据
    data = request.json
    # 检查是否提供了必要的字段
    if not data or 'interface_name' not in data or 'input_data' not in data or 'output_data' not in data:
        return jsonify({'error': '缺少必需的字段:interface_name, input_data, output_data'}), 400
    # 提取数据
    interface_name = data['interface_name']
    input_data = data['input_data']
    output_data = data['output_data']
    # 创建一条新的记录
    mock_data = MockData(
        interface_name=interface_name,
        input_data=input_data,
        output_data=output_data
    )
    db.session.add(mock_data)
    db.session.commit()
    # 返回成功信息
    return jsonify({'message': '模拟数据预填充成功'}), 201
@app.route('/mock/', methods=['POST'])
def mock_endpoint(interface_name):
    # 添加调试输出以检查 interface_name 的值
    print("接收到的 interface_name:", interface_name)
    # 手动添加斜杠到 interface_name
    interface_name_with_slash = '/' + interface_name
    # 获取请求中的 input_data
    input_data = request.json.get('input_data') if request.json else None
    # 使用 SQLAlchemy ORM 查询
    query = MockData.query.filter_by(interface_name=interface_name_with_slash)
    # 如果 input_data 为空,则查询所有与 interface_name 匹配的记录
    if input_data is None:
        result = query.first()
    else:
        # 如果 input_data 存在,则添加到查询条件
        query = query.filter_by(input_data=input_data)
        result = query.first()
    # 添加调试输出
    print("使用 ORM 执行查询")
    print("查询参数:", {'interface_name': interface_name_with_slash, 'input_data': input_data})
    print("结果:", result)
    if result is None:
        # 返回 JSON 格式的错误响应
        return jsonify({'error': f'未找到接口 "{interface_name_with_slash}" 和输入数据 "{input_data}" 的模拟数据'}), 404
    # 将 output_data 转换为 JSON 对象
    output_json = json.loads(result.output_data)
    # 返回模拟出参
    return jsonify(output_json), 200
if __name__ == '__main__':
    # 创建所有表
    db.create_all()
    # 读取环境变量或使用默认端口
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port, debug=True)

代码说明

配置 MySQL 数据库连接:

app.config['SQLALCHEMY_DATABASE_URI'] 设置了 MySQL 数据库的连接字符串。

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] 设置为 False,禁用不必要的修改跟踪。

初始化数据库对象:

db = SQLAlchemy(app) 初始化了一个 SQLAlchemy 对象 db,用于操作数据库。

定义数据模型:

MockData 类定义了 mockdata 表的结构,包含 id, interface_name, input_data, output_data, timestamp 字段。

创建新的路由来预先填充数据:

/mock/prepopulate 路由接收 POST 请求,用于向数据库中插入新的模拟数据记录。

创建路由处理模拟请求:

/mock/路由接收 POST 请求,根据 interface_name 和 input_data 查找对应的模拟数据,并返回 output_data。

运行应用:

if __name__ == '__main__': 确保当脚本直接运行时才启动 Flask 应用。

db.create_all() 创建所有数据库表。

app.run(host='0.0.0.0', port=port, debug=True) 启动 Flask 应用,监听指定端口,并启用调试模式。

调用示例-demoRequests.py

# 设置模拟数据
import requests
def send_post_request():
    url = "http://127.0.0.1:5000/mock/prepopulate"  # 注意这里的 URL 更改为 /prepopulate
    test_data = {
        "interface_name": "/hmrInfoSend/upload",  # 指定接口
        "input_data": "{\"userid\": \"09242901\",\"password\": \"p09242901\"}",  # 设定请求数据
        "output_data": "{\"test1_output_template\": \"设定返回数据0924290122222222221231231231\"}"  # 设定返回数据
    }
    headers = {"Content-Type": "application/json"}
    # 使用 json 参数来发送 JSON 数据
    response = requests.post(url, json=test_data, headers=headers)
    # 输出响应状态码和 JSON 内容
    print(f"返回数据 状态码: {response.status_code}")
    print(f"返回数据 JSON: {response.json()}")
def send_post_request_with_input_data():
    url = "http://127.0.0.1:5000/mock/hmrInfoSend/upload"
    headers = {"Content-Type": "application/json"}
    input_data = "{\"test1_input_template\": \"设定请求数据09242901\"}"
    # 发送 POST 请求
    response = requests.post(url, json={"input_data": input_data}, headers=headers)
    # 输出响应状态码和 JSON 内容
    print(f"返回数据 状态码: {response.status_code}")
    print(f"返回数据 JSON: {response.json()}")
if __name__ == '__main__':
    send_post_request()  # 将对应数据存储到数据库中
    # send_post_request_with_input_data()  # 根据请求的数据和接口,获取对应的数据

代码说明

设置模拟数据:

send_post_request 函数用于向 /mock/prepopulate 接口发送 POST 请求,以预先填充模拟数据。

test_data 是一个字典,包含 interface_name(接口名称)、input_data(请求数据)和 output_data(返回数据)。

headers 设置了请求头,指定内容类型为 application/json。

requests.post 方法发送 POST 请求,并传递 json 参数和 headers。

打印响应的状态码和 JSON 内容。

发送带有输入数据的 POST 请求:

send_post_request_with_input_data 函数用于向 /mock/hmrInfoSend/upload 接口发送 POST 请求,并传递 input_data。

headers 设置了请求头,指定内容类型为 application/json。

requests.post 方法发送 POST 请求,并传递 json 参数和 headers。

打印响应的状态码和 JSON 内容。

主程序:

if __name__ == '__main__': 确保当脚本直接运行时才执行以下代码。

send_post_request() 调用 send_post_request 函数,将模拟数据存储到数据库中。

注释掉的 send_post_request_with_input_data() 用于根据请求的数据和接口获取对应的数据。

最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

在这里插入图片描述

### 如何在Python Flask框架中使用Mock进行单元测试 为了在Flask应用中执行有效的单元测试,通常会利用`unittest`库中的`patch`方法来模拟(mock)外部依赖项的行为。这使得开发者可以在不调用实际资源的情况下验证代码逻辑。 对于Flask应用程序而言,在编写测试案例时,可以通过创建一个测试客户端实例来进行HTTP请求的发送并接收响应。下面展示了一个简单的例子说明怎样设置这样的环境以及如何运用`unittest.mock.patch()`函数来替代真实的数据库查询或其他耗时操作: ```python from unittest import TestCase from unittest.mock import patch import my_flask_app # 假设这是要被测试的应用程序模块名 class TestMyApp(TestCase): def setUp(self): self.app = my_flask_app.app.test_client() self.app.testing = True @patch('my_flask_app.some_function') def test_demo_endpoint_with_mock(self, mock_some_function): # 设置mock返回值 mock_some_function.return_value = {'status': 'success'} response = self.app.get('/demo') # 发送GET请求到/demo路由 # 断言状态码为200 OK self.assertEqual(response.status_code, 200) # 验证some_function确实被调用了 assert mock_some_function.called is True ``` 上述代码片段展示了如何定义一个继承自`TestCase`类的测试类,并在其内部定义具体的测试方法。这里特别注意的是`setUp()`方法用于准备每次测试前的状态;而`test_demo_endpoint_with_mock()`则具体实现了针对某个API端点的功能测试[^1]。 当涉及到更复杂的场景比如POST请求或者带有参数的情况时,则可以根据实际情况调整测试用例的内容。例如处理JSON数据提交的情形下,可以这样构建测试: ```python @app.route('/submit_data', methods=['POST']) def submit_data(): data = request.json result = process_data(data) # 这里假设process_data是我们想要mock的方法 return jsonify(result) # 对应的测试代码可能看起来像这样: @patch('my_flask_app.process_data') def test_submit_data_with_json(mock_process_data): payload = {"key": "value"} # 设定mock行为 mock_process_data.return_value = {"processed_key": "processed_value"} resp = client.post( '/submit_data', content_type='application/json', data=json.dumps(payload), ) expected_result = {"processed_key": "processed_value"} actual_result = json.loads(resp.data.decode()) assert resp.status_code == 200 assert actual_result == expected_result ``` 这段示例进一步扩展了之前的概念,不仅包了对不同类型的HTTP请求的支持,还涉及到了JSON格式的数据交换过程。通过这种方式,即使是在开发初期阶段缺乏完整的后端支持情况下也能顺利开展前端界面或者其他组件的相关工作[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值