接口自动化测试实战之Python操作数据库、接口关联及相关管理优化

一、前言

本文章主要会讲解接口自动化测试中Python如何操作数据库、为何要操作数据库,有哪些利弊,以及数据库断言、相关的接口关联的测试

二、自动化数据库理论与操作

2.1 接口自动化为何要操作数据库

接口自动化中操作数据库主要是根据业务层面决定的,部分情况例如查询手机号、或个人信息时需要操作数据库,有时候也有可能需要删除某个内容,通常而言不会这么做罢了。

2.2 接口自动化操作数据库的利弊

"""
利:
1、能够根据我们需要的业务情况来解决一定的业务问题

弊:
1、数据库的操作本身就会让自动化变得慢,需要建立连接 -- 查询 等等
2、数据库本身是一种依赖, 我们能不操作数据库尽可能不操作
"""

2.3 Python操作数据库

要操作数据库,需要先进行pymysql库的安装,按照对应语法填写好对应数据即可:

import pymysql

"""
1、连接数据库:输入用户名,密码,地址,端口
2、游标:使用游标读取数据、修改数据(执行sql语句)
3、获取操作结果
4、关闭游标
5、关闭数据库连接
"""

conn = pymysql.connect(user="future",
                password="XXXXXX",
                host="XX.XX.XX.XX",
                port=3306
)

cursor = conn.cursor()

# 执行sql
sql = "SELECT mobile_phone,id,reg_name FROM XXXXXXX.member WHERE mobile_phone = 137XXXXXXXX"
cursor.execute(sql)

# 获取一个结果每条记录用元组表示
res = cursor.fetchone()
print(res)

# 关闭
cursor.close()
conn.close()

 

输出的数据是元组,元组数据不可修改,我们需要进行类型转换,如要输出字典,需要加上DictCursor:

import pymysql
from pymysql.cursors import DictCursor

"""
1、连接数据库:输入用户名,密码,地址,端口
2、游标:使用游标读取数据、修改数据(执行sql语句)
3、获取操作结果
4、关闭游标
5、关闭数据库连接
"""

conn = pymysql.connect(user="future",
                password="XXXXXX",
                host="XX.XX.XX.XX",
                port=3306
)

cursor = conn.cursor(DictCursor)

# 执行sql
sql = "SELECT mobile_phone,id,reg_name FROM XXXXXXX.member WHERE mobile_phone = 137XXXXXXXX"
cursor.execute(sql)

# 获取一个结果每条记录用元组表示
res = cursor.fetchone()
print(res)

# 关闭
cursor.close()
conn.close()

 

2.4 操作数据库封装

我们需要进行函数封装,数据库内容也属于公用内容,也可以放入至common包下,函数封装后:

class DBHandler:

    def __init__(self, host=setting.db_host, port=setting.db_port,
                 user=setting.db_user, password=setting.db_pwd):
        self.conn = pymysql.connect(user=user,
                                    password=password,
                                    host=host,
                                    port=port,
                                    autocommit=True
                                    )

    def query_one(self, sql, cursor_type=DictCursor):
        cursor = self.conn.cursor(cursor_type)
        cursor.execute(sql)
        data = cursor.fetchone()
        cursor.close()
        return data

    def query_all(self, sql, cursor_type=DictCursor):
        cursor = self.conn.cursor(cursor_type)
        cursor.execute(sql)
        data = cursor.fetchall()
        cursor.close()
        return data

    def query(self, sql, one=True, cursor_type=DictCursor):
        if one:
            return self.query_one(sql, cursor_type)
        return self.query_all(sql, cursor_type)

    def close(self):
        self.conn.close()

    # 自己实现上下文管理器
    # def __enter__(self):
    #     return self
    #
    # def __exit__(self, exc_type, exc_val, exc_tb):
    #     return self.close()


db_module = DBHandler()

if __name__ == '__main__':
    db = DBHandler()
    sql = 'select mobile_phone from futureloan.member limit 5'
    res = db.query(sql, one=False)
    db.close()
    print(res)
    #

    # with DBHandler_2() as db:
    #     sql = 'select mobile_phone from futureloan.member limit 5'
    #     res = db.query(sql, one=False)
    #     print(res)
# 数据库配置项
db_host = "XX.XX.XX.XX"
db_port = XXXX
db_user = "future"
db_pwd = "XXXXXX"

三、校验数据库、接口关联及项目优化

自动化测试用例执行后,判断成功的测试用例才进行数据库的校验:

import unittest
import requests
import json

from common.db import DBHandler, db_module
from common.logger import log
from common.excel import read_excel
from common import helper
from config import path_config
from unittestreport import ddt, list_data
from config import setting

# 获取数据
data = read_excel(path_config.case_path , 'XXXXXX')

@ddt
class TestRegister(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        """测试类的前置"""
        cls.db = DBHandler()

    @classmethod
    def tearDownClass(cls) -> None:
        """测试类的前置"""
        cls.db.close()

    @list_data(data)
    def test_register(self, case_data):
        print(case_data)
        json_data = case_data['json']
        if '#new_phone#' in json_data:
            new_phone = helper.generate_new_phone()
            json_data = json_data.replace('#new_phone#', new_phone)

        # 把json格式的字符串转化成字典
        json_data = json.loads(json_data)
        headers = json.loads(case_data['headers'])

        print("替换之后", json_data)

        resp = requests.request(
            method=case_data['method'],
            url= setting.host +  case_data['url'],
            json=json_data,
            headers=headers
        )

        actual = resp.json()
        print(actual)
        try:
            self.assertEqual(case_data['expected'], actual['code'])
        except AssertionError as e:
            raise e

"""
1、判断是否是注册成功的测试用例
2、查询数据库是否包含了手机号的记录
3、判断数据库记录条数是否为1
"""
        if actual['msg'] == "OK":
            # 通过 setUp 创建数据库连接
            sql = f"select id from XXXX.XXXX where XXXXXX = {json_data['XXXXXX']}"
            result = self.db.query_all(sql)
            self.assertEqual(1, len(result))

 

往往项目中的接口都会存在接口关联,而我们就需要对接口进行单独处理:

import unittest
import requests
import json
from jsonpath import jsonpath
from decimal import Decimal

from common.db import DBHandler
from common.logger import log
from common.excel import read_excel
from common import helper
from config import path_config
from unittestreport import ddt, list_data
from config import setting

# 获取数据
from middle import api

data = read_excel(path_config.case_path , 'XXXXXX')

@ddt
class TestRecharge(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        """
        1,访问登录接口,得到返回值
        2,从返回值当中提取数据:resp["data"]["id"]
        3, 从返回值当中提取数据:resp["data"]["token_info"]["token"]
        4, 设置成类属性,方便测试用例函数当中调用
        :return:
        """
        resp_data = api.login()
        # 提取方式1:
        cls.member_id = resp_data["data"]["id"]
        cls.token = resp_data["data"]["token_info"]["token"]

        # 提取方式2:jsonpath
        cls.member_id = jsonpath(resp_data, '$..id')[0]
        cls.token = jsonpath(resp_data, '$..token')[0]
        cls.before = jsonpath(resp_data, '$..leave_amount')[0]

        # 初始化数据库
        cls.db = DBHandler()

    @classmethod
    def tearDownClass(cls) -> None:
        pass

    @list_data(data)
    def test_recharge(self, case_data):
        """
        1, 获取 case_data 当中的数据,headers, json 是要重点关注的。
        2, 数据的预处理:数据替换,数据转化成 字典格式:headers, json, expected
        3, 发送请求
        4, 断言
        :param case_data:
        :return:
        """
        # 获取 case_data当中的数据,headers, json是要重点关注的。
        headers_string = case_data['headers']
        json_string = case_data['json']

        # 数据的预处理:数据替换,数据转化成字典格式:headers, json, expected
        if "#token#" in headers_string:
            headers_string = headers_string.replace("#token#", self.token)
        if "#member_id#" in json_string:
            json_string = json_string.replace("#member_id#", str(self.member_id))

        headers = json.loads(headers_string)
        json_data = json.loads(json_string)
        expected = json.loads(case_data['expected'])


        # 获取充值之前数据库当中用户的余额
        sql = f"select XXXXXXX from XXXX.XXXXX where id={self.XXXXX_id}"
        before = self.db.query_one(sql)
        # {"leave_amount": 200}


        # 3, 发送请求
        resp = requests.request(
            method=case_data['method'],
            url=setting.host + case_data['url'],
            json=json_data,
            headers=headers
        )

        # 4, 断言
        json_response = resp.json()

        try:
            for key, value in expected.items():
                self.assertEqual(value, json_response[key])
        except AssertionError as e:
            log.error(f"测试用例失败:{e}")
            raise e


        if json_response['msg'] == 'OK':
            print(json_response)
            # 通过数据库断言
            sql = f"select leave_amount from futureloan.member where id={self.member_id}"
            after = self.db.query_one(sql)
            money = str(json_data['amount'])
            after = str(after['leave_amount'])
            before = str(before['leave_amount'])
            self.assertEqual(Decimal(money), Decimal(after) - Decimal(before))

四、总结

关于接口自动化测试中Python如何操作数据库、为何要操作数据库,有哪些利弊,以及数据库断言、相关的接口关联的测试,笔者就说到这里了,喜欢的小伙伴可以收藏点赞评论,加关注哟,关注我每天给你不同的惊喜。
 

最后:下面是配套学习资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

软件测试面试小程序

被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!

涵盖以下这些面试题板块:

1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux

6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

  全套资料获取方式:点击下方小卡片自行领取即可

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值