常用的自动化测试库包括request的封装,邮件发送的封装,随机数的封装,日志封装,加密解密的封装
1.request库封装
import requests
import json
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
from retrying import retry
class RequestAPI:
def __init__(self):
pass
@retry(stop_max_attempt_number=3)
def send_get(self, url, data, params, header, files):
r = requests.get(url=url, data=json.dumps(data), params=params, headers=header, files=files, timeout=60,
verify=False)
return r
@retry(stop_max_attempt_number=3)
def send_post(self, url, data, header, files):
if files == None:
r = requests.post(url=url, data=json.dumps(data), headers=header, files=files, timeout=60, verify=False)
return r
else:
r = requests.post(url=url, data=data, headers=header, files=files, timeout=60, verify=False)
return r
@retry(stop_max_attempt_number=3)
def send_put(self, url, data, header, files):
r = requests.put(url=url, data=json.dumps(data), headers=header, files=files, timeout=60, verify=False)
return r
@retry(stop_max_attempt_number=3)
def send_delete(self, url, data, header, files):
r = requests.delete(url=url, data=json.dumps(data), headers=header, files=files, timeout=60, verify=False)
return r
def yichang(self):
print('暂无除get\post\put\delete请求外的method')
def ObtainCookie(self, url):
responseCookie = requests.put(url)
responseHeaders = urllib3.HTTPResponse.getheaders(responseCookie)
cookie = responseHeaders['set-cookie']
cookienew = cookie.split(';')[0]
return cookienew
def run_main(self, url, method, data=None, params=None, headers=None, files=None):
if method == 'GET':
r = self.send_get(url, data, params, headers, files)
elif method == 'POST':
r = self.send_post(url, data, headers, files)
elif method == 'PUT':
r = self.send_put(url, data, headers, files)
elif method == 'DELETE':
r = self.send_delete(url, data, headers, files)
else:
r = self.yichang()
return r
request = RequestAPI()
2.随机数的封装
# coding=utf-8
import random
import time
from datetime import date, datetime, timedelta
from .randomdata import *
import uuid
import string
class Random():
def __init__(self):
pass
def getStr(self, length):
strlist = random.choices("abcdefghijklmnopqrstuvwxyz", k=length)
string = ''.join(strlist)
return string
def getNum(self, length):
strlist = random.choices("0123456789", k=length)
num = ''.join(strlist)
return num
def getNumByRange(self, minRange, maxRange):
"""
获取指定范围的随机整数
"""
num = random.randint(minRange, maxRange)
return num
def getSomeNum(self, count, minRang=0, maxRange=1000):
"""
获取n个随机整数
"""
numlist = []
for u in range(count):
num = random.randint(minRang, maxRange)
numlist.append(num)
return numlist
def getMixedCharacter(self, count):
"""
获取随机字符串、数字、特殊字符(如密码)
"""
massage = ''.join(random.sample(string.ascii_letters + string.digits + string.punctuation, count))
return massage
def getEmail(self):
"""
邮箱
"""
return self.getStr(5) + self.getNum(3) + "@histudy.com"
def getSex(self):
"""
性别
"""
return random.choice(('男', '女'))
def getAge(self):
"""
年龄
"""
return str(random.randint(1, 120))
def getPhone(self):
"""
电话号码
"""
prelist = ["130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "147", "150", "151", "152",
"153", "155", "156", "157", "158", "159", "181", "186", "187", "188"]
return random.choice(prelist) + "".join(random.choices("0123456789", k=8))
def getAddress(self):
"""
地址
"""
villagelist = random.sample(STRINGUNICODE, random.randint(2, 3))
village = ''.join(villagelist) + "村"
streetlist = random.sample(STRINGUNICODE, random.randint(2, 3))
street = ''.join(streetlist) + "街"
housenum = "".join(random.choices("0123456789", k=3)) + "号"
return random.choice(PROVINCE_LIST) + random.choice(CITY_LIST) + random.choice(
AREA_LIST) + village + street + housenum
def getName(self):
"""
姓名
"""
sur = random.choice(SURNAME_LIST)
name = random.choice(FIRSTNAME_LIST)
return "{0}{1}".format(sur, name)
def _generateCheckCode(self, idCard):
"""
身份证最后1位,校验码
"""
def haoma_validate(idCard):
if type(idCard) in [str, list, tuple]:
if len(idCard) == 17:
return True
raise Exception('Wrong argument')
if haoma_validate(idCard):
if type(idCard) == str:
seq = map(int, idCard)
elif type(idCard) in [list, tuple]:
seq = idCard
else:
raise TypeError
t = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
s = sum(map(lambda x: x[0] * x[1], zip(t, map(int, seq))))
b = s % 11
bd = {
0: '1',
1: '0',
2: 'X',
3: '9',
4: '8',
5: '7',
6: '6',
7: '5',
8: '4',
9: '3',
10: '2'
}
return bd[b]
def getIdcard(self):
"""
身份证
"""
cur = datetime.now()
id = str(random.choice(CITYCODE_LIST)) # 地区码
id = id + str(random.randint(cur.year - 100, cur.year - 18)) # 年份项
da = date.today() + timedelta(days=random.randint(1, 366)) # 月份和日期项
id = id + da.strftime('%m%d')
id = id + str(random.randint(100, 300)) # 顺序号简单处理
id = id + self._generateCheckCode(id)
return id
def getDate(self):
"""
日期(如生日)
"""
cur = datetime.now()
randomdate = str(random.randint(cur.year - 100, cur.year))
da = date.today() + timedelta(days=random.randint(1, 366)) # 月份和日期项
randomdate = randomdate + da.strftime('%m%d')
return randomdate
def getHobby(self):
"""
兴趣爱好
"""
HobbySum = random.randint(1, 10)
hobbylist = random.sample(HOBBY_LIST, HobbySum)
hobby = '/'.join(hobbylist)
return hobby
def getBank(self):
"""
开户银行
"""
return random.choice(BANK_LIST)
def getBank_subbranch(self, bankname):
"""
开户银行支行
"""
cityname = random.choice(CITY_LIST)
return bankname + random.choice(AREA_LIST) + "支行"
def getBankcardno(self):
"""
银行卡号
"""
return random.choice(CARDBIN_LIST) + "".join(
random.choice("0123456789") for i in range(10))
def getTimexint(self):
"""
获取时间戳
"""
return str(time.time()).replace('.', '')
def getChinese(self, length):
"""
获取大量汉字
"""
messagelist = random.sample(STRINGUNICODE, length)
message = ''.join(messagelist)
return message
def getMessage(self, length):
"""
获取大量数据段
"""
message = ''.join(random.sample(STRINGUNICODE + string.ascii_letters + string.digits + string.punctuation, length))
return message
def getUUID(self):
return "".join(str(uuid.uuid4()).split("-")).upper()
randMethod = Random()
if __name__ == '__main__':
rand1 = Random()
print("几个随机数:", rand1.getSomeNum(6))
# print("手机号码:", rand1.getPhone())
# print("姓名:", rand1.getName())
# print("邮箱:", rand1.getEmail())
# print("身份证:", rand1.getIdcard())
# print("日期:", rand1.getDate())
# print("兴趣:", rand1.getHobby())
# bankname = rand1.getBank()
# print("开户银行:", bankname)
# Bank_subbranch = rand1.getBank_subbranch(bankname)
# print("银行支行:", Bank_subbranch)
# print("银行卡号:", rand1.getBankcardno())
# print("地址:", rand1.getAddress())
# print("一段话:", rand1.getMessage(100))
print("字符串:", rand1.getName())
# print("随机数:", rand1.getNum(3))
# print("密码:", rand1.getStrAndNum(15))
# print("文字:", rand1.getMessage(100))
3.发送邮件的封装
import smtplib, time, os
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
from histudy.encryptdecrypt import EncryptDecrypt
encryptdecrypt=EncryptDecrypt()
encryptkey=b'\sdkjskdsjd'
decryptpassword = encryptdecrypt.decrypt(encryptkey, encryptdecrypt.aes())
sendemailconfig = {
"sender": '12333@126.com',
"smtpserver": 'smtp.exmail.qq.com',
"username": 'adsds@126.com',
"password": decryptpassword.strip()
}
class SendEmail():
def sendemail(self, subject, content, receiver, attachment):
t = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
self.msg = MIMEMultipart('related')
msgtext = MIMEText(content, _subtype='html', _charset='utf-8')
self.msg['Subject'] = Header(subject + t, 'utf-8')
self.msg['From'] = sendemailconfig["sender"]
self.msg['To'] = ",".join(receiver)
self.msg.attach(msgtext)
# 附件发送邮件
if attachment is not None:
for signle_attachment in attachment.split(','):
filename = os.path.split(signle_attachment)[1]
att = MIMEText(open(signle_attachment, "rb").read(), "base64", "utf-8")
att["Content-Type"] = "application/octet-stream"
att.add_header("Content-Disposition", "attachment", filename=("gbk", "", filename))
self.msg.attach(att)
try:
smtp = smtplib.SMTP()
smtp.connect(sendemailconfig["smtpserver"])
smtp.login(sendemailconfig["username"], sendemailconfig["password"])
smtp.sendmail(sendemailconfig["sender"], receiver, self.msg.as_string())
except:
print("邮件发送失败!")
else:
print("邮件发送成功!")
finally:
smtp.quit()
send = SendEmail()
if __name__ == '__main__':
# pass
subject = "这是一个测试的邮件 "
conent = "这个是一个有附件的和内容的邮件,您收到了吗?" # 需要发送内容可以是HTML,也可以是文件,文件会被附件发送出去,如果想要发送文件中的内容,需要通过读取文件内容后再传给content发送邮件
# attachment="./test/111.txt,1.png" #发送多附件
attachment = None #无附件
receiver = 'abcde@126.com','abcd@126.com' #可以发送多个人 'lsqiong_1@histudy.com','guohb@histudy.com'
send =SendEmail()
send.sendemail(subject, conent, receiver, attachment) # 发送邮件
4.企业微信机器人发送
#!/usr/bin/env python3
from histudy import request
import base64
import hashlib
class SendRobotByImage():
def sendReportByRobot(self, filename, roboturl):
with open(filename, 'rb') as f:
image = f.read()
image_base64 = str(base64.b64encode(image), encoding='utf-8')
image_base65 = "" + image_base64
image_md5 = hashlib.md5(image).hexdigest()
body = {
"msgtype": "image",
"image": {
"base64": image_base65,
"md5": image_md5
}
}
header = {
"Content-Type": "application/json"
}
try:
response = request.run_main(
roboturl,
method="POST", headers=header, data=body)
if response.json()["errcode"] == 0:
print(f"发送成功:{response.text}")
else:
print(f"发送失败:{response.text}")
except Exception as error:
raise error
sendRobotByImage = SendRobotByImage()
if __name__ == '__main__':
SendRobotByImage().sendReportByRobot("report.png",
"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=84f2ea6e-b7f2-4d16-acf5-3434343")
5.日志封装
# coding=utf-8
import logging.handlers
import os
class Logger(logging.Logger):
def __init__(self):
super(Logger, self).__init__("loginit")
# 日志文件名
pwd = os.getcwd()
filename = pwd + '/logs'
if not os.path.exists(filename):
os.makedirs(filename)
filename = filename + '/logger.log'
self.filename = filename
print(self.filename)
# 创建一个handler,用于写入日志文件 (每天生成1个,保留30天的日志)
fh = logging.handlers.TimedRotatingFileHandler(self.filename, 'D', 1, 30, encoding='utf-8')
fh.suffix = "%Y%m%d-%H%M.log"
fh.setLevel(logging.DEBUG)
# 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# 定义handler的输出格式
formatter = logging.Formatter(
'[%(asctime)s] - %(filename)s - %(funcName)s [Line:%(lineno)d] - [%(levelname)s] - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# 给logger添加handler
self.addHandler(fh)
self.addHandler(ch)
log = Logger()
6.数据库的封装
# -*- coding: utf-8 -*-
import configparser
import pymysql as mdb
import os
import cx_Oracle as ora
import sys
"""
单例模式获取数据连接
"""
def singleton (cls, *args, **kwargs):
instances = {}
def get_instance(*args, **kwargs):
if args not in instances:
instances[args] = cls(*args, **kwargs)
return instances[args]
return get_instance
"""
数据库操作
"""
def dao(db,sql):
cur = Conn(db)
# print(cur)
if sql.lower().startswith("select"):
return cur.query(sql)
else:
return cur.modify(sql)
@singleton
class Conn(object):
sql = []
db = None
cursor = None
# 初始化
def __init__(self, dbname):
file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "db.conf")
config = configparser.RawConfigParser()
config.read(file)
conf = config[dbname]
db_type = conf['type']
host = conf['host']
port = conf['port']
database = conf['database']
user = conf['user']
pwd = conf['pwd']
if db_type == 'mysql':
charset = conf['charset']
self.db = mdb.connect(host=host, port=int(port), user=user, passwd=pwd, db=database, charset=charset)
self.cursor = self.db.cursor(cursor=mdb.cursors.DictCursor)
if db_type == 'oracle':
# 设置字符集
os.environ['NLS_LANG'] = 'AMERICAN_AMERICA.AL32UTF8'
self.db = ora.connect(user + '/' + pwd + '@' + host + ':' + port + '/' + database)
self.cursor = self.db.cursor()
# 关闭游标,关闭连接
def __del__(self):
self.cursor.close()
self.db.close()
# 查询数据
def query(self, sql, count=0):
if sql is not None and '' != sql:
sql = sql.strip()
self.db.commit()
self.cursor.execute(sql)
# if int(count):
# return self.cursor.fetchmany(count)
# else:
# return self.cursor.fetchall()
if "pymysql" in str(type(self.cursor)):
return self.cursor.fetchall()
if "cx_Oracle" in str(type(self.cursor)):
columns = [col[0] for col in self.cursor.description]
return [
dict(zip(columns, row))
for row in self.cursor.fetchall()
]
else:
print("sql is null")
# 修改数据
def modify(self, sql):
if sql is not None and '' != sql:
# print(sql)
sql = sql.strip()
self.cursor.execute(sql)
self.db.commit()
else:
print("sql is null")
# 执行sql文件
def execfile(self, fname):
resultList = []
# 判断文件是否存在
if os.path.exists(fname):
file = open(fname, 'r', encoding='UTF-8')
while 1:
line = file.readline()
if '' != line:
line = line.strip()
# 如果以select开头,调用查询的接口
if line.lower().startswith('select'):
resultList.append(self.query(line))
else:
self.modify(line)
if not line:
break
pass
# 如果只有一条记录,返回
if len(resultList) > 0:
if len(resultList) == 1:
return resultList[0]
else:
return resultList
file.close()
else:
print(fname + " 文件不存在")
if __name__ == '__main__':
sql1 = "delete from tab_table01 where id = 111111110"
sql2 = "insert into tab_table02 (ID, name, SEX, ID_ID,)" + \
"values (111111110, '数据库测试1', 0, null)"
sql3 = "select * from tab_table03 where rownum <= 3"
sql4 = "SELECT * from tab_table04 limit 3"
list = dao("abc_64", sql4)
print(list)
list1 = dao("efg_test",sql3)
print(list1)
print(dao("xxx_rls","select * from tab_table05 where rownum <= 3"))
将以上的代码放到打包上传到nexus服务器上
import os, subprocess, shutil
version = "0.0.62"
class init:
def __init__(self):
system_user_path = os.path.expanduser('~')
if os.path.exists(system_user_path):
shutil.copy(".pypirc", system_user_path)
pip_dir = system_user_path + "\pip"
if os.path.exists(pip_dir):
pass
else:
os.mkdir(system_user_path + "\pip")
shutil.copy("pip/pip.ini", system_user_path + "\pip")
subprocess.run(
'pip install --extra-index-url http://nexus.example.com/repository/pypi_group/simple tools==' + version + ' --trusted-host nexus.example.net',
shell=True)
subprocess.run(['pip', 'install', '-r', 'requirements.txt'])
@staticmethod
def package():
subprocess.run(['pip', 'install', 'twine'])
import twine
subprocess.run(['python', 'setup.py', 'sdist', 'build'])
subprocess.run(['twine', 'upload', '-r', 'pypi-test', 'dist/*'])
if __name__ == '__main__':
init()
init.package()
以上是一些常用的封装内容,如果各位测试同行们有用得上的可以拿去用,也可以在这个基础上改,对于接口自动化来讲这些都是基础的方法封装。
最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。