赞
踩
本文章主要会讲解接口自动化测试中Python如何操作数据库、为何要操作数据库,有哪些利弊,以及数据库断言、相关的接口关联的测试
接口自动化中操作数据库主要是根据业务层面决定的,部分情况例如查询手机号、或个人信息时需要操作数据库,有时候也有可能需要删除某个内容,通常而言不会这么做罢了。
- """
- 利:
- 1、能够根据我们需要的业务情况来解决一定的业务问题
- 弊:
- 1、数据库的操作本身就会让自动化变得慢,需要建立连接 -- 查询 等等
- 2、数据库本身是一种依赖, 我们能不操作数据库尽可能不操作
- """
要操作数据库,需要先进行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()
我们需要进行函数封装,数据库内容也属于公用内容,也可以放入至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、计算机基础
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。