记录下自己第一次部署pytest框架的过程
本人是一个新人小白,每天搜索大量的资料,从中获取到一些有用的知识点及踩坑指南,今天分享给各位
一、框架的搭建,一旦框架搭建好了之后,后面我们只需要维护测试用例即可
二、首先安装该框架所必须的包,我们把包写在requirements.txt中,然后在终端Terminal中执行pip install -r requirements.txt 命令
pytest.ini,注意这是pytest的规范,不可随意变更名称
三、common包下的config.py
import pymysql
#定义一个类去数据库中查询
class database():
def select_database(self):
# 查询数据库
# 打开数据库
#数据库IP地址,用户名,密码,数据库
db = pymysql.connect(host='localhost', user='root', password='password', database='qys4.3.0')
# 使用cursor()方法创建一个游标对象cursor
cursor = db.cursor()
# 使用execute()方法执行sql查询,sql语句为你想要查询的,我当前的语句是查询“未认证”的公
#司id及名称
cursor.execute('SELECT id,name from company where status = "UNREGISTERED"')
# 使用fetchone()方法获取单条数据
# data = cursor.fetchone()
Not_certified_company=''
# 使用fetchall()方法获取所有数据,以元组形式返回
try:
data = cursor.fetchall()
Not_certified_company = data[0][1]
except Exception:
print('没有未认证的公司')
#关闭数据库
db.close()
#返回一个字段,主要是用于后面直接给用例一个参数
return Not_certified_company
common下的log.py,日志文件直接拿去用,不用做任何修改
# coding:utf-8
import logging,time
import os
# log_path是存放日志的路径
cur_path = os.path.dirname(os.path.realpath(__file__))
log_path = os.path.join(os.path.dirname(cur_path), 'logs')
# 如果不存在这个logs文件夹,就自动创建一个
if not os.path.exists(log_path): os.mkdir(log_path)
class Log():
def __init__(self):
# 文件的命名
self.logname = os.path.join(log_path, '%s.log' % time.strftime('%Y_%m_%d'))
self.logger = logging.getLogger()
self.logger.setLevel(logging.DEBUG)
# 日志输出格式
self.formatter = logging.Formatter('[%(asctime)s] - %(filename)s] - %(levelname)s: %(message)s')
def __console(self, level, message):
# 创建一个FileHandler,用于写到本地
#fh = logging.FileHandler(self.logname, 'a') # 追加模式 这个是python2的
fh = logging.FileHandler(self.logname, 'a', encoding='utf-8') # 这个是python3的
fh.setLevel(logging.DEBUG)
fh.setFormatter(self.formatter)
self.logger.addHandler(fh)
# 创建一个StreamHandler,用于输出到控制台
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(self.formatter)
self.logger.addHandler(ch)
if level == 'info':
self.logger.info(message)
elif level == 'debug':
self.logger.debug(message)
elif level == 'warning':
self.logger.warning(message)
elif level == 'error':
self.logger.error(message)
# 这两行代码是为了避免日志输出重复问题
self.logger.removeHandler(ch)
self.logger.removeHandler(fh)
# 关闭打开的文件
fh.close()
def debug(self, message):
self.__console('debug', message)
def info(self, message):
self.__console('info', message)
def warning(self, message):
self.__console('warning', message)
def error(self, message):
self.__console('error', message)
if __name__ == "__main__":
log = Log()
log.info("---测试开始----")
log.info("操作步骤1,2,3")
log.warning("----测试结束----")
common下的send_eamil.py,以qq邮箱为例,前提是需要在qq邮箱中开启smtp,可自行百度
# -- coding: utf-8 --
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import importlib
import sys
importlib.reload(sys)
import os
import smtplib
class Email():
def send_email(self, file_path):
# param file_path index.html 路径
smtpserver = 'smtp.qq.com'
# 设置登录邮箱的账号和授权密码,以qq邮箱为例
user = 'xxx@qq.com'
password = 'xxx' # 此处是授权码,不是邮箱密码
sender = 'xxx@qq.com'
# # 可添加多个收件人的邮箱
receives = ['xxx@qq.com']
# # 构造邮件对象
msg = MIMEMultipart('mixed')
# # 定义邮件的标题
subject = '自动化测试报告'
# HTML邮件正文,定义成字典
msg['Subject'] = Header(subject, "utf-8")
msg['From'] = sender
msg['To'] = ','.join(receives) # 这里注意,直接用receivers是不行的会报错
# 构造文字内容
text_plain = MIMEText("附件是最新自动化测试报告,请查看!", 'html', 'utf-8')
msg.attach(text_plain)
# 构造附件
f = open(file_path, 'rb')
mail_body = f.read()
f.close()
text_attr = MIMEText(mail_body, 'base64', 'utf-8')
text_attr["Content-type"] = 'application/octet-stream'
text_attr['Content-Disposition'] = 'attachment; filename = "index.html"'
msg.attach(text_attr)
#下面的路径是你当前项目的路径
with open(os.path.join(
r"C:\Users\wzb\PycharmProjects\localhost000\reports", "index.html"),
'rb') as f:
mail_body = f.read() # 读取测试报告的内容
# 将测试报告的内容放在邮件的正文当中
html = MIMEText(mail_body, _subtype='html', _charset='utf-8')
# 将html附加在msg里
msg.attach(html)
print(mail_body)
# 邮箱设置时勾选了SSL加密连接,进行防垃圾邮件,SSL协议端口号要使用465
smtp = smtplib.SMTP_SSL(smtpserver, 465)
# 向服务器标识用户身份
smtp.helo(smtpserver)
# 向服务器返回确认结果
smtp.ehlo(smtpserver)
# 登录邮箱的账号和授权密码
smtp.login(user, password)
print("开始发送邮件...")
# 开始进行邮件的发送,msg表示已定义的字典
smtp.sendmail(sender, receives, msg.as_string())
smtp.quit()
print("已发送邮件")
四、reports、temps、log新建好即可,无需操作
五、新建一个testcase的包,注意需要以test开头,在其中我们可以建我们的测试用例,在用例中我们可以用logger.py打印出我们需要的一个日志信息如下图:在控制台和日志文件中都是会显示出来的
用例的代码,新入门的小白
import requests
from common.logger import Log
class TestLogin:
base_url = 'http://xxx'
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Connection': 'keep-alive',
'Content-Length': '222',
'Content-Type': 'application/x-www-form-urlencoded',
'Cookie': 'SID=ac8d59a9-8ee0-40b4-882b-bb54cd61aacb',
'I18N-Language': 'zh_CN',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest',
}
log = Log()
def test_right_login(self):
'''正确的用户名密码'''
url = self.base_url + '/login'
data = {
'username':'xxx',
'password':'xxx'
}
self.log.info('我是日志,我等会被打印出来')
rep = requests.post(url,data=data,headers=self.headers)
print(rep.json())
assert rep.json()['message'] == '登陆成功'
def test_falseusername_login(self):
'''错误的用户名'''
url = self.base_url+'/login'
data = {
'username':xxx,
'password':'xxx'
}
rep = requests.post(url,data=data,headers=self.headers)
#print(rep.json())
assert rep.json()['message'] == '用户不存在或密码有误!'
def test_falsepassword_login(self):
'''错误的密码'''
url = self.base_url+'/login'
data = {
'username': xxx,
'password': 'xxx'
}
rep = requests.post(url,data=data,headers=self.headers)
#print(rep.json())
assert rep.json()['message'] == '用户不存在或密码有误!'
六、run.py,注意,该python文件的位置是在根目录下,在此运行,可以运行包括用例,日志,测试报告,发送邮件的等
import os
import time
import pytest
from common.send_emails import Email
if __name__ == '__main__':
pytest.main()
time.sleep(3)
os.system('allure generate ./temps -o ./reports --clean')
#发送邮件
#time.sleep(5)
# e = Email()
# report = "./reports/index.html"
# e.send_email(report)
七、最终效果
八、注意事项
(1)若出现 “UnicodeDecodeError: 'gbk' codec can't decode byte 0xad in position 98: illegal multibyte sequence”类似编码情况,注意是不是我们在一些特定的文件中包含了中文,如下图,当时花了好久时间才知道到底是哪出现问题。
(2)这个坑也是搞了好久才搞明白,报错的提示根本与我们的错误无关,当时也是搜了大量资料也是无济于事,偶然情况下才发现是这个原因
(3)pytest的编辑地址,最好别动
新人小白,写的不好,请各位手下留情,多多指教