使用Flask搭建一个简单的接口自动化测试服务

1. 说明

目的:使用Flask搭建一个简单的可用于接口自动化的API服务。

包含文件:

  1. api_server.py: 定义5个接口,分别是查询用户信息列表、查询单个用户信息、增加用户、修改用户信息和删除用户
  2. test_api.py: 测试api_server.py中定义的接口。
  3. users.json: 保存用户信息。这里没有采用数据库存储数据,采用json文件存储。

环境:
Python 3.9.12
Flask 2.1.2

2. 使用

2.1. 简单使用

  1. 首先,安装Flask环境,同时要确保python版本大于3.6(因为里面使用了Python f-string格式化字符串的语法)
  2. 接着,运行api_server.py文件,此时会在本地监听8888端口。
  3. 然后,在test_api.py中运行对应的单元测试用例即可测试对应的接口。

2.2. 接口支持内容

GET     http://[hostname]/users                 获取用户列表
GET     http://[hostname]/user/[user_id]        获取user_id的用户信息
POST    http://[hostname]/users                 创建新用户
PUT     http://[hostname]/users/[user_id]       更新用户信息
DELETE  http://[hostname]/users/[user_id]       删除user_id的用户信息    

2.3. 用户信息结构

用户主要包含name、age、like这3部分信息,同时还存在1个唯一的id标识,用于区分用户。如下:

{
    "id": 1001,
    "name": "Jim",
    "age": "20",
    "like": "jogging"
}

3. 相关代码

3.1. api_server.py

from flask import jsonify, Flask, request
import json
"""
功能:实现一个简单的用户查询、增加、修改和删除的api接口,可用于接口自动化测试的api服务。
响应结果说明:
1. api请求成功,则返回状态码200,同时在响应结果中返回api请求的相关信息,比如:
    {
        "result": "success",
        "users": {xxx}
    }
2. api请求失败,则返回状态码400,同时在响应结果中返回失败的原因,比如:
    {
        "result": "There is no user with user_id:xxx"
    }
    
依赖环境:
Python 3.9.12
Flask   2.1.2
"""

app = Flask(__name__)
json_path = "./users.json"      # 保存用户json信息的路径

def get_json(json_path):
    """读取json数据"""
    with open(json_path, "r", encoding="utf-8") as f:
        res = json.load(f)
    return res

def write_json(json_path, json_data):
    """向文件写入json数据"""
    with open(json_path, "w", encoding="utf-8") as f:
        json.dump(json_data, f)


@app.route("/users", methods=["GET"])
def get_users():
    """获取所有用户信息"""
    users = get_json(json_path)["users"]
    res = {
        "result": "success",
        "users": users
    }
    return jsonify(res), 200

@app.route("/users/<int:user_id>", methods=["GET"])
def get_user(user_id):                          # 需要将route中的参数传递进来
    """查询指定user_id的用户信息"""
    users = get_json(json_path)["users"]
    user = list(filter(lambda t: t["id"] == user_id, users))        # 获取users中id为user_id的用户列表。
    if len(user) == 0:
        return jsonify({"result": f"There is no user with user_id:{user_id}"}), 400
    else:
        return jsonify({"result": "success","user": user[0]}), 200


@app.route("/users", methods=["POST"])
def create_user():
    """要求请求的json数据中name、age是必填项,like选填"""
    required = ["name", "age"]          # 设置必填参数
    users = get_json(json_path)["users"]
    req_json = request.json
    if not req_json:
        return jsonify({"result": "Please use application/json to submit json data"}), 400

    # 获取缺少的必填参数
    params_list = set(required) - set(req_json.keys())
    if len(params_list) > 0:
        return jsonify({"result": f"Missing required parameter:{params_list}"}), 400

    # 为新用户设置一个id:
    # 1. 如果没有传递id参数,且当前users中不存在用户信息,此时就设置id为1001。
    # 2. 如果没有传递id参数,且users中存在用户信息,此时就获取最大的用户id,并在此基础上+1,作为new_id。
    # 3. 如果传递了id参数,且这个id已经存在与已有的id,此时返回错误信息。
    # 4. 如果传递了id参数,但是这个id不存在,此时就赋值为用户传递的id。
    ids = [user["id"] for user in users]
    if "id" not in req_json.keys():
        if len(ids) == 0:
            new_id = 1001
        else:
            new_id = max(ids) + 1
    else:
        if int(req_json["id"]) in ids:          # 如果自定义的id已经存在,则此时需要返回提示信息
            res = {"result": f'user_id: {req_json["id"]} already exists'}
            return jsonify(res), 400
        else:
            new_id = int(req_json["id"])

    # 新的用户数据
    user = {
        "id": new_id,
        "name": req_json["name"],
        "age": req_json["age"],
        "like": req_json["like"] if "like" in req_json.keys() else ""
    }
    users.append(user)
    print(users)
    write_json(json_path, {"users": users})
    return jsonify({"user":user, "result": "success"}), 200


@app.route("/users/<int:user_id>", methods=["PUT"])
def update_user(user_id):
    users = get_json(json_path)["users"]
    user = list(filter(lambda t: t["id"] == user_id, users))
    if len(user) == 0:          # 表示不存在id为user_id的用户
        return jsonify({"result": f"There is no user with user_id:{user_id}"}), 400
    if not request.json:        # 当没有提交数据或者数据没有提交到json
        return jsonify({"result": "Please use application/json to submit json data"}), 400

    # 这里修改user[0],实际上会修改users里面的内容,user应该也是users中指定id的引用
    user[0]["name"] = request.json.get("name", user[0]["name"])
    user[0]["age"] = request.json.get("age", user[0]["age"])
    user[0]["like"] = request.json.get("like", user[0]["like"])

    write_json(json_path, {"users": users})
    return jsonify(user), 200

@app.route("/users/<int:user_id>", methods=["DELETE"])
def delete_user(user_id):
    users = get_json(json_path)["users"]
    user = list(filter(lambda t: t["id"] == user_id, users))
    if len(user) == 0:          # 表示不存在id为user_id的用户
        return jsonify({"result": f"There is no user with user_id:{user_id}"}), 400

    # 直接通过remove删除即可。
    users.remove(user[0])
    write_json(json_path, {"users": users})
    return jsonify(user), 200



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

3.2. test_api.py


import requests
import unittest
import json

class APITest(unittest.TestCase):
    # 请求的路径
    base_url = "http://127.0.0.1:8888"

    def test_get_users(self):
        """测试获取用户列表"""
        path = "/users"
        url = f"{self.base_url}{path}"

        res = requests.get(url, params={"token":"1234555"})
        print(res.json())
        assert res.json()["result"] == "success"

    def test_create_user(self):
        """
        创建用户
        """
        path = "/users"
        url = f"{self.base_url}{path}"
        data = {
            "name": "Jim",
            "age": "20",
            "like": "abc",
        }
        res = requests.post(url, headers={"Content-Type": "application/json"},data=json.dumps(data))
        print(res.json())
        assert res.json()["result"] == "success"

    def test_update_user(self):
        path = "/users/1001"
        url = f"{self.base_url}{path}"
        data = {
            "name": "Jim",
            "age": "23",
            "like": "jogging",
        }
        res = requests.put(url, headers={"Content-Type": "application/json"}, data=json.dumps(data))
        print(res.json())

    def test_delete_user(self):
        path = "/users/1001"
        url = f"{self.base_url}{path}"
        res = requests.delete(url)
        print(res.json())

3.3. users.json

{
  "users": [
  ]
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值