文章目录
- 一、基于代码实现自动化
-
- [1.1 代码实现自动化相关理论](#1.1 代码实现自动化相关理论)
- [1.2 代码实现接口自动化步骤](#1.2 代码实现接口自动化步骤)
- 二、具体代码框架实现
-
- [2.1 api](#2.1 api)
-
- [2.1.1 __ init __.py](#2.1.1 __ init __.py)
- [2.1.2 api_register_login.py](#2.1.2 api_register_login.py)
- [2.1.3 api_approve_trust.py](#2.1.3 api_approve_trust.py)
- [2.1.4 api_recharge.py](#2.1.4 api_recharge.py)
- [2.1.5 api_tender.py](#2.1.5 api_tender.py)
- [2.1.6 api_factory.py](#2.1.6 api_factory.py)
- [2.2 script](#2.2 script)
-
- [2.2.1 test01_register_login.py](#2.2.1 test01_register_login.py)
- [2.2.2 test02_approve_trust.py](#2.2.2 test02_approve_trust.py)
- [2.2.3 test03_recharge.py](#2.2.3 test03_recharge.py)
- [2.2.4 test04_tender.py](#2.2.4 test04_tender.py)
- [2.2.5 test05_tender_list.py](#2.2.5 test05_tender_list.py)
- [2.3 data](#2.3 data)
-
- [2.3.1 register_login.json](#2.3.1 register_login.json)
- [2.3.2 tender.json](#2.3.2 tender.json)
- [2.4 config.py](#2.4 config.py)
- [2.5 tool.py](#2.5 tool.py)
- [2.6 log](#2.6 log)
- [2.7 report](#2.7 report)
- [2.8 pytest.ini](#2.8 pytest.ini)
- 三、持续集成
- 四、小技巧
-
- [4.1 接口参数化步骤](#4.1 接口参数化步骤)
- [4.2 日志](#4.2 日志)
- [4.3 抛异常](#4.3 抛异常)
一、基于代码实现自动化
1.1 代码实现自动化相关理论
- 代码编写脚本和工具实现脚本区别是啥?
yacas
代码︰
- 优点:代码灵活方便
- 缺点:学习成本高
工具:
- 优点:易上手
- 缺点:灵活度低,有局限性。
1.2 代码实现接口自动化步骤
yacas
1、抽取功能用例作为自动化用例;
2、搭建环境(测试工具)
3、搭建目录结构
4、实现测试脚本(实现目录结构中内容)
5、运行调试
6、持续集成
1、抽取功能用例作为自动化用例:

2、搭建环境(测试工具)
python
python解释器+pycharm(集成开发工具)+requests+pytest(测试框架,用例管理和执行的框架)+allure+parameterize参数化
3、搭建目录结构
yacas
思想:分层
重点:
1、api(封装-被测接口封装实现)
2、script(调用-测试业务)
辅助:
3、log(日志-存储脚本运行日志)
4、data(测试数据)
5、report(测试报告)
6、tools(工具)
7、config.py (公共变量)
8、pytest.ini (pytest框架配置文件)
4、实现测试脚本(实现目录结构中内容)
5、运行调试
6、持续集成
二、具体代码框架实现

2.1 api
2.1.1 __ init __.py
python
from tool import GetLog
# 日志器
log = GetLog.get_log()
2.1.2 api_register_login.py
python
import requests
from api import log
from config import BASE_URL
""""
重点:封装注册登录模块相关被测的接口
"""
class ApiRegisterLogin():
# 初始化
def __init__(self, session):
# 获取session对象。
# 谁用谁传入,传过来的session变成实例属性。因为下面的接口调用,需要调用session相关的方法。
self.session = session
# 获取图片验证码url
self.__url_img_code = BASE_URL + "/common/public/verifycode1/{}"
# 获取短信验证码url
self.__rl_phone_code = BASE_URL + '/member/public/sendSms'
# 注册接口url
self.__url_register = BASE_URL + '/member/public/reg'
# 登录接口url
self.__url_login = BASE_URL + '/member/public/login'
# 查询登录状态url
self.__url_login_status = BASE_URL + '/member/public/islogin'
# 1、获取图片验证码接口 封装
def api_img_code(self, random):
log.info("正在调用获取图片验证码接口,请求方法:get 请求url: {}".format(self.__url_img_code.format( random)))
# 调用get方法,传入图片验证码url
return self.session.get(url = self.__url_img_code.format(random))
# 2、获取短信验证码接口 封装
def api_phone_code(self,phone,imgVerifyCode):
#①定义请求参数
data = {'phone': phone,'imgVerifyCode': imgVerifyCode ,'type':'reg'}
log.info("正在调用获取短信验证码接口,请求方法:post 请求url: {} 请求参数:{}".format(self.__url_phone_code,data))
#②调用请求方法
response = self.session.post(url = self.__url_phone_code,data=data)
#返回响应
return response
# 3、注册接口封装 封装
def api_register(self,phone,password,imgVerifyCode,phone_code):
data = {"phone": phone,
"password": password,
"verifycode": imgVerifyCode,
"phone_code": phone_code,
"dy_server": "on",
'invite_phone':" "}
log.info("正在调用注册接口,请求方法:post 请求url: {} 请求参数:{}".format(self.__url_register,data))
response = self.session.post(url=self.__url_register, data=data)
return response
# 4、登录接口 封装
def api_login(self,keywords,pwd):
data = {"keywords": keywords,"password": pwd}
log.info("正在调用登录接口,请求方法:post 请求url: {} 登录参数:{}".format(self.__url_login,data))
response = self.session.post(url=self.__url_login, data=data)
return response
# 5、查询接口 封装
def api_login_status(self):
log.info("正在调用查询登录状态接口,请求方法:post 登录url: {}".format(self.__url_login_status))
return self.session.post(url = self.__url_login_status)
2.1.3 api_approve_trust.py
python
from config import BASE_URL
class ApiApproveTrust():
# 初始化
def __init__(self, session):
# 获取session对象,将实例化创建的session对象传过来,然后变成实例属性
self.session = session
# 认证url
self.__url_approve = BASE_URL + '/member/realname/approverealname'
# 查询认证状态url
self.__url_approve_status = BASE_URL + '/member/member/getapprove'
# 开户url(后台开户)
self.__url_trust = BASE_URL + '/trust/trust/register'
# 1、认证接口 封装
def api_approve(self,session,realname,cardId):
# ① 请求数据
data = {"realname": realname, "card_id": cardId}
# ②调用方法,难点请求要求multipart-form/data -->data +files
response = self.session.post(self.__url_approve, data=data, files={'x': 'y'})
return response
# 2、查询认证状态接口封装
def api_Approve_status(self):
return self.session.post(url = self.__url_approve_status)
# 3、开户封装
def api_trust(self):
return self.session.post(url = self.__url_trust)
2.1.4 api_recharge.py
python
from api import log
from config import BASE_URL
class ApiRecharge:
def __init__(self):
# 获取session对象
self.session = session
# 充值验证码url
self.__url_code = BASE_URL + "/common/public/verifycode/{}"
# 后台充值url
self.__url_recharge = BASE_URL + "/trust/trust/recharge"
"""测试几个接口,封装几个"""
# 1、充值验证码接口,封装
def api_img_code(self, random):
log.info("正在调用充值验证码接口,请求方法get 请求url:{}".format(self.__url_code.format(random)))
# 调用get方法
return self.session.get(url = self.__url_code.format(random))
# 2、后台充值接口,封装
def api_recharge(self, data):
data = {
"paymentType": "chinapnrTrust",
"amount": 100000,
"formStr": "reForm"
"valicode":"8888"
}
log.info("正在后台充值接口,请求方法post 请求url:{} 请求参数".format(self.__url_recharge, data))
return self.session.post(url = self.__url_recharge, data = data)
2.1.5 api_tender.py
python
from config import BASE_URL
class ApiTender:
# 初始化
def __init__(self):
# 获取session
self.session = session
# 后台投资url
self.__url_tender = BASE_URL + "/trust/trust/tender"
# 后台投资接口封装
def api_tender(self, amount):
# 请求参数
data = {
"id": 642,
"depositCertificate": -1,
"amount":amount,
}
# 请求方法
return self.session.post(url=self.__url_tender, data=data)
2.1.6 api_factory.py
python
# 工厂模式,管理所有的api
from api.api_approve_trust import ApiApproveTrust
from api.api_recharge import ApiRecharge
from api.api_register_login import ApiRegisterLogin
from api.api_tender import ApiTender
class ApiFactory:
def __init__(self):
self.session = session
# 获取注册登录api对象
def get_register_login(self):
return ApiRegisterLogin(self.session)
# 获取认证api对象
def get_approve(self):
return ApiApproveTrust(self.session)
# 获取开户充值api对象
def get_recharge(self):
return ApiRecharge(self.session)
# 获取投资对象
def get_tender(self):
return ApiTender(self.session)
2.2 script
2.2.1 test01_register_login.py
python
import requests
from api import log
from api.api_register_login import ApiRegisterLogin
from tool import common_assert, read_json, clear_data
class TestRegisterLogin:
def setup_class(cls):
log.info("正在清除数据库注册数据····")
# 只能用类方法,调用清除测试数据
clear_data()
log.info("数据库注册数据清理完成")
# 初始化
def setUp(self):
# 创建session对象
self.session = requests.Session()
log.info("正在获取session对象:{}".format(self.session))
# 获取 ApiRegisterLogin实例对象
self.api=ApiRegisterLogin(self.session)
log.info("正在获取ApiRegisterLogin实例对象:{}".format(self.api))
# 结束
def tearDown(self):
# 关闭session对象
self.session.close()
log.info("正在关闭session对象:{}".format(self.session))
"""" 测试方法 """
# 1、图片验证码接口测试
@pytest.mark.parametrize("random,expect_code",read_json("register_login.json","img_code"))
def test01_img_code(self,random,expect_code):
try:
result = self.api.api_img_code(random)
log.info("图片验证码接口返回结果:{}".format(result.status_code))
common_assert(result,status_code=expect_code)
log.info("图片验证码断言通过")
print(result.status_code)
except Exception as e:
# 捕获异常的目的就是记录错误日志
print("错误:", e)
log.error(e)
# 抛异常
raise
# 2、短信验证码接口测试
@pytest.mark.parametrize("phone,imgVerifyCode,expect_json", read_json("register_login.json", "phone_code"))
def test02_phone_code(self,phone,imgVerifyCode,expect_json):
try:
# ①请求图片验证码
self.api.api_img_code(123123)
# ②调用手机短信接口
result = self.api.api_phone_code(phone,imgVerifyCode)
log.info("短信验证码接口返回结果:{}".format(result.text))
common_assert(result, expect_json=expect_json)
log.info("短信验证码断言通过") # 如果这句话输出,说明上面断言通过
print(result.json())
except Exception as e:
# 捕获异常的目的就是记录错误日志
print("错误:", e)
log.error(e)
# 抛异常
raise
# 3、注册接口测试
@pytest.mark.parametrize("phone,password,imgVerifyCode,phone_code,expect_json",read_json("register_login.json","register"))
def test03_register(self,phone,password,imgVerifyCode,phone_code,expect_json):
try:
# ① 调用图片验证码
self.api.api_img_code(123123)
# ② 调用手机验证码
self.api.api_phone_code(phone,imgVerifyCode)
# ③调用注册接口
result = self.api.api_register(phone,password,imgVerifyCode=imgVerifyCode,phone_code=phone_code)
log.info("注册接口返回结果:{}".format(result.text))
common_assert(result, expect_json=expect_json)
log.info("注册接口断言通过")
except Exception as e:
# 捕获异常的目的就是记录错误日志
print("错误:", e)
log.error(e)
# 抛异常
raise
# 4、登录接口测试,
# 这个参数化最难,如何处理错误密码业务逻辑
@pytest.mark.parametrize("keywords,password,expect_json",read_json("register_login.json", "login"))
def test04_login(self,keywords,password,expect_json):
try:
i = 1
result = None
if password == "error123":
while i<=3:
result = self.api.api_login(keywords, password)
log.info("登录接口返回结果:{}".format(result.text))
i +=1
assert "锁定" in result.text
log.info("登录-->锁定断言通过")
sleep(60)
# 登录成功 ->判断解锁
result = self.api.api_login("13600001111", "test123")
log.info("登录接口返回结果:{}".format(result.text))
common_assert(result, expect_json=expect_json)
log.info("登录接口断言通过")
else:
result = self.api.api_login(keywords,password)
common_assert(result, expect_json=expect_json)
except Exception as e:
# 捕获异常的目的就是记录错误日志
print("错误:", e)
log.error(e)
# 抛异常
raise
# 5、查询登录状态接口 测试
@pytest.mark.parametrize("status,expect_json",read_json("register_login.json", "login_status"))
def test05_login_status(self,status,expect_json):
try:
if status == "已登录":
# 调用登录
self.api.api_login("13600001111","test123")
# 调用查询登录状态接口
result = self.api.api_login_status()
log.info("查询登录状态接口返回结果:{}".format(result.text))
common_assert(result, expect_json=expect_json)
log.info("查询登录状态接口断言通过")
except Exception as e:
# 捕获异常的目的就是记录错误日志
print("错误:", e)
log.error(e)
# 抛异常
raise
2.2.2 test02_approve_trust.py
python
import requests
from api import log
from api.api_approve_trust import ApiApproveTrust
from api.api_register_login import ApiRegisterLogin
from tool import common_assert, html_parser
class TestApproveTrust:
# 初始化
def setUp(self):
# 获取session对象
self.session = requests.session()
# 获取ApiApproveTrust对象
self.api = ApiApproveTrust(self.session)
# 获取ApiRegisterLogin对象并调用登录
ApiRegisterLogin(self.session).api_login("13600001111", "test123")
# 结束
def tearDown(self):
self.session.close()
# 1、认证接口测试
def test01_approve(self,expect_json = "提交成功"):
try:
# 调用认证接口
result = self.api.api_approve()
log.info('认证接口执行结果为:{}'.format(result.text))
common_assert(result, expect_json=expect_json)
log.info('认证接口断言通过')
except Exception as e:
log.error(e)
raise
# 2、查询认证状态接口测试
def test02_approve_status(self, expect_text = "1111"):
try:
# 查询认证状态接口
result = self.api.api_Approve_status()
log.info('查询认证状态接口执行结果为:{}'.format(result.text))
common_assert(result, expect_text=expect_text)
log.info('查询认证状态接口断言通过')
except Exception as e:
log.error(e)
raise
# 3、后台开户接口测试
def test03_trust(self,expect_text="form",expect_text2= "ok"):
try:
# 后台开户接口
result = self.api.api_trust()
log.info('后台开户接口执行结果为:{}'.format(result.json()))
common_assert(result, expect_text=expect_text)
log.info('后台开户接口断言通过')
# 三方开户如何实现?-依赖后台开户响应结果
data = html_parser(result)
result = self.session.post(url=data[0], data=data[1])
print("三方开户执行结果为:", result.text)
common_assert(result, expect_text=expect_text2)
log.info('三方开户执行结果为:{}'.format(result.text))
except Exception as e:
log.error(e)
raise
2.2.3 test03_recharge.py
python
import requests
from api import log
from api.api_recharge import ApiRecharge
from api.api_register_login import ApiRegisterLogin
from tool import html_parser, common_assert
class TestRecharge:
# 初始化
def setup(self):
# 获取session对象
self.session = requests.session()
# 获取ApiRecharge实例对象
self.api = ApiRecharge(self.session)
# 登录
ApiRegisterLogin(self.session).api_login()
# 结束
def teardown(self):
self.session.close()
# 充值验证码接口测试方法
def test01_img_code(self, random=123123):
try:
result = self.api.api_img_code(random)
print(result.status_code)
log.info("充值验证码执行结果为:{}".format(result.status_code))
except Exception as e:
log.error(e)
raise
# 后台充值接口测试方法
def test02_recharge(self,expect_text="OK"):
try:
self.api.api_img_code(random)
result = self.api.api_recharge()
print(result.status_code)
log.info("后台充值接口执行结果为:{}".format(result.json()))
# 三方充值如何实现?-依赖后台开户响应结果
data = html_parser(result)
result = self.session.post(url=data[0], data=data[1])
print("三方开户执行结果为:", result.text)
common_assert(result, expect_text=expect_text)
log.info('三方充值执行结果为:{}'.format(result.text))
except Exception as e:
log.error(e)
raise
2.2.4 test04_tender.py
python
import requests
from api import log
from api.api_register_login import ApiRegisterLogin
from api.api_tender import ApiTender
from tool import html_parser, common_assert
class TestTender:
# 初始化
def setup(self):
# 获取session对象
self.session = requests.session()
# 获取ApiTender实例对象
self.api = ApiTender(self.session)
# 登录
ApiRegisterLogin(self.session).api_login()
# 结束
def teardown(self):
self.session.close()
@pytest.mark.parametrize("amount,expect_text", read_json("tender.json","tender"))
def test01_tender(self,amount,expect_text):
try:
result = self.api.api_tender(amount)
log.info("后台投资接口为:{}".format(result.json()))
if expect_text == "OK":
# 三方充投资如何实现?-依赖后台开户响应结果
data = html_parser(result)
result = self.session.post(url=data[0], data=data[1])
log.info('三方投资执行结果为:{}'.format(result.text))
common_assert(result, expect_text=expect_text)
except Exception as e:
log.error(e)
raise
2.2.5 test05_tender_list.py
python
from api import log
from api.api_factory import ApiFactory
import requests
from tool import html_parser
class TestTenderList:
# 初始化
def setup(self):
self.session = requests.session()
self.api = ApiFactory(self.session)
# 结束
def teardown(self):
self.session.close()
def test01_tender_list(self):
try:
# 1、获取图片验证码接口
self.api.get_register_login().api_img_code(123123)
# 2、获取短息验证码接口
self.api.get_register_login().api_phone_code("13600001111",8888)
# 3、注册接口
self.api.get_register_login().api_register("13600001111","test123","8888",666666)
# 4、登录接口
self.api.get_register_login().api_login()
# 5、认证接口
self.api.get_approve().api_approve()
# 6、后台开户接口
result = self.api.get_approve().api_trust()
# 7、三方开户
data = html_parser(result)
result = self.session.post(url=data[0], data=data[1])
log.info('三方开户接口执行结果为:{}'.format(result.text))
# 8、充值验证码接口
self.api.get_recharge().api_img_code(88881123)
# 9、后台充值接口
result = self.api.get_recharge().api_recharge()
# 10、三方充值接口
data = html_parser(result)
result = self.session.post(url=data[0], data=data[1])
log.info('三方充值接口执行结果为:{}'.format(result.text))
# 11、后台投资接口
result = self.api.get_tender().api_tender(100)
# 12、三方投资接口
data = html_parser(result)
result = self.session.post(url=data[0], data=data[1])
log.info('三方投资接口执行结果为:{}'.format(result.text))
except Exception as e:
log.error(e)
raise
2.3 data
2.3.1 register_login.json
json
{
"img_code": [
{
"desc": "获取图片验证码成功(随机整数)",
"random": 123123,
"expect": 200
},
{
"desc": "获取图片验证码成功(随机小数)",
"random": 0.123123,
"expect": 200
},
{
"desc": "获取图片验证码失败(随机数为空)",
"random": "",
"expect": 404
},
{
"desc": "获取图片验证码失败(随机数为字符串)",
"random": "123123a",
"expect": 400
}
],
"phone_code": [
{
"desc": "获取短信验证码成功",
"phone": "13600001111",
"imgVerifyCode": "8888",
"expect_json": "成功"
},
{
"desc": "获取短信验证码失败(图片验证码错误)",
"phone": "13600001111",
"imgVerifyCode": "8889",
"expect_json": "错误"
}
],
"register": [
{
"desc": "注册成功",
"phone": "13600001111",
"password": "test123",
"verifycode": "8888",
"phone_code": "6666",
"expect_json": "成功"
},
{
"desc": "注册失败(图片验证码错误)",
"phone": "13600001112",
"password": "test123",
"verifycode": "8889",
"phone_code": "6666",
"expect_json": "错误"
},
{
"desc": "注册失败(手机验证码错误)",
"phone": "1360000112",
"password": "test123",
"verifycode": "8888",
"phone_code": "6666",
"expect_json": "错误"
},
{
"desc": "注册失败(手机号已注册)",
"phone": "13600001111",
"password": "test123",
"verifycode": "8888",
"phone_code": "6666",
"expect_json": "已存在"
}
],
"login": [
{
"desc": "登录成功",
"keywords": "13600001111",
"password": "test123",
"expect_json": "成功"
},
{
"desc": "登录失败(手机号未注册)",
"keywords": "13600001112",
"password": "test123",
"expect_json": "不存在"
},
{
"desc": "登录失败(密码为空)",
"keywords": "13600001111",
"password": "",
"expect_json": "为空"
},
{
"desc": "登录成功(锁定)",
"keywords": "13600001111",
"password": "error123",
"expect_json": "成功"
}
],
"login_status": [
{
"desc": "查询登录状态(已登录)",
"status": "已登录",
"expect_json": "ok"
},
{
"desc": "查询登录状态(未登录)",
"status": "已登录",
"expect_json": "未登"
}
]
}
2.3.2 tender.json
json
{
"tender": [
{
"desc":"后台投资成功",
"amount": 100,
"expect_text": "OK"
},
{
"desc":"请求后台投资失败(金额为空)",
"amount": "",
"expect_text": "不是正确的金额"
}
]
}
2.4 config.py
python
import os
# 项目服务器地址
BASE_URL = "http://user-p2p-test.itheima.net"
# 项目目录
DIR_PATH = os.path.dirname(__file__)
2.5 tool.py
python
# 断言工具封装
# response响应结果,响应对象传过来
import os, json, logging.handlers
from bs4 import BeautifulSoup
from config import DIR_PATH
import pymysql
def common_assert(response,status_code=None,expect_json=None,expect_text=None):
# 如果status_code不为空,那么就断言
if status_code:
assert response.status_code == status_code, "状态码断言错误,预期状态码:{} != 实际状态码:{}".format(status_code,response.status_code)
if expect_json:
assert expect_json in response.json().get("description"), " json断言错误.实际结果:{} 不包含 预期结果:{}".format(response.json().get("description"),expect_json)
if expect_text:
assert expect_text in response.text, "text断言错误, 响应结果:{} 不包含 预期结果:{}".format(response.text,expect_text)
# 读取json工具
def read_json(filename,key):
filepath = DIR_PATH + os.sep + "data" + os.sep + filename
arrs = []
with open(filepath,"r",encoding="utf-8") as f:
for data in json.load(f).get(key):
arrs.append(tuple(data.values())[1:])
return arrs
# 日志工具
# 封装成类,保证对象的使用是同一个对象,否则多处调用会产生多个对象,在多事引用每行的记录都是重复的
class GetLog:
log = None
@classmethod
def get_log(cls):
if cls.log == None:
# 1、初始化日志对象
cls.log = logging.getLogger()
# 2、设置日志级别,大写表示全局变量
cls.log.setLevel(logging.INFO)
# 3、创建控制台日志处理器和文件日志处理器
filepath = DIR_PATH + os.sep + "log" + os.sep + "p2p.log"
tf = logging.handlers.TimedRotatingFileHandler(filename = filepath,when="midnight",interval=1,backupCount=3,encoding="utf-8")
# 4、设置日志格式,创建格式器
fm = '%(asctime)s %(levelname)s [%(name)s] [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s'
fmt = logging.Formatter(fm)
# 5、将格式化器设置到日志处理器中
tf.setFormatter(fmt)
# 6、将日志处理器添加到日志对象
cls.log.addHandler(tf)
return cls.log
# 提取html信息
def html_parser(result):
# 1、提取html.result.json()得到字典格式的数据
html = result.json().get("description").get("form")
# 2、获取bs对象
bs = BeautifulSoup(html,"html.parser")
# 3、提取url
url = bs.form.get("action")
data = {}
# 4、提取所有input数据
for input in bs.find_all("input"):
data[input.get("name")] = input.get("value")
return url,data # 以逗号分割,返回元祖
# 连接数据库共库
def connect_mysql():
conn = None
cursor = None
try:
# 获取连接对象
conn = pymysql.connect(host="121.43.169.97",port=3306,user="root",password="p2p_student_2022",database="czbk_member",charset="utf8",autocommit= True)
# 获取游标对象
cursor = conn.cursor()
# 执行sql语句
cursor.execute(sql)
# 返回什么结果
if sql.lower().split()[0] == "select":
# 返回所有结果
return cursor.fetchall()
else:
return cursor.rowcount
except Exception as e:
print(e)
# 回滚
conn.rollback()
finally:
# 关闭游标对象
if cursor:
cursor.close()
# 关闭连接对象
if conn:
conn.close()
# 清除数据
def clear_data():
# python中不支持批量执行sql语句
sql_1 = "delete info.* from mb_member as mb inner join mb_member_info as info on info.member_id = mb.id where mb.phone in ("13600001111","13600001112","13600001113","13600001114");"
connect_mysql(sql_1)
sql_2 = "delete login.* from mb_member as mb inner join mb_member_login_log as login on login.member_id = mb.id where mb.phone in ("13600001111","13600001112","13600001113","13600001114");"
connect_mysql(sql_2)
sql_3 = "delete from mb_member where phone in ("13600001111","13600001112","13600001113","13600001114");"
connect_mysql(sql_3)
sql_4 = "delete from mb_member_register_log where phone in ("13600001111","13600001112","13600001113","13600001114");"
connect_mysql(sql_4)
if __name__ == '__main__':
print(read_json("register_login.json","login_status"))
GetLog.get_log().info("信息级别测试")
"""
分析:parametrize ---> [()]
核心:
1、从json文件中读取数据
2、再组装到列表、元祖中
"""
2.6 log
2.7 report
2.8 pytest.ini
ini
[pytest]
addopts = -s --alluredir report
testpaths = ./script
python_files = test*.py
python_classes = Test*
python_functions = test*

三、持续集成
1、代码推上去和gitee代码管理。

2、启动 jenkins.war包。
shell
java -jar jenkins.war
3、在jekins中,新建一个任务,选择"构建一个自由风格的软件项目"。然后配置源码和运行。

4、先从gitee上克隆仓库代码,然后运行

四、小技巧
4.1 接口参数化步骤
json
1、编写数据存储文件json
2、编写读取工具方法 read_json()
3、使用参数化组件进行引用parametrize
json
心得:
1、根据模块来新建json文件(1个模块1个json文件)
2、最外侧使用{},模块下几个接口,编写几个key,值为列表
3、列表值中,单接口有几组数据,就写几个[}.
4、每个{}中,组成格式:说明+要进行参数的参数+预期结果
json
// 有几个接口,写几个key,值为列表。 在api_register_login.py中有5个接口
// []中有几组数据,就有几个{}
4.2 日志
yacas
作用:
1、记录程序运行步骤
2、记录程序运行错误
位置:
api层:info(记录步骤执行请求url、参数、方法)
scripts层:执行结果+错误(捕获的异常)
4.3 抛异常
python
try:
result = self.api.api_img_code(random)
common_assert(result,status_code=200)
print(result.status_code)
except Exception as e:
# 捕获异常的目的就是记录错误日志
print("错误:", e)
# 抛异常
raise