Python自动化Selenium单元测试page object设计模式框架设计流程
程序员文章站
2022-04-10 17:05:05
...
本文章将Selenium单元测试page object设计模式框架表述完整流程
本章来测试,github登录小功能
设计架构:
目录结构:
代码流程描述:
1. 创建AutoTest_project 主目录
2. 创建driver 目录
实现功能 设计启动浏览器驱动方法
1 导入启动浏览器驱动(我用的是chromedriver).
创建 driver.py
from selenium import webdriver
# 在无头浏览器中使用
# from selenium.webdriver.chrome.options import Options
def browser():
driver = webdriver.Chrome(
executable_path='/home/lbc/PycharmProjects/new_system/simplicity/util/AutoTest_project/driver/chromedriver'
)
# driver = webdriver.PhantomJS()
# driver = webdriver.Firefox()
# driver.get("http://www.baidu.com")
return driver
if __name__ == '__main__':
browser()
# chrome 无头浏览器
# chrome_options = Options()
# chrome_options.add_argument('--headless')
# driver = webdriver.Chrome(
# executable_path='/home/lbc/PycharmProjects/new_system/simplicity/util/AutoTest_project/driver/chromedriver'
# , chrome_options=chrome_options
# )
# 打印页面源码
# print(driver.page_source)
3. 创建Website 目录
实现功能 目录包含 test_case目录,test_report目录
test_case目录功能: 包含 model目录,page_object目录
test_login: 测试登录用例 设计登录方式 调用各类模块 截图 存报告 发邮箱
run_test.py: 执行test_login:.py用例
model目录:
function.py: 测试快照截图,检测时间为最新的报告文件,邮箱自动发送:发送内容及附件文件
myunit.py: unittest方法的起始执行 结束执行
test_send_png.py: 自行创建 为了设计测试快照截图文件的发送位置 而进行的测试文件(与主文件无关)
page_object目录:
BasePage.py: page_object设计模式从调用 driver目录 启动chromedriver驱动 发送链接
效验链接 打开浏览器 执行元素选中
Login_Page.py: 继承BasePage.py方法 设置子链接 封装定位器设计元素名字 清理元素框内容并输入内容的一类封装方法 方便后期调用 效验登录模块 成功后的两值是否相同
test_report目录: 包含测试报告文件 screenshot截图文件目录
4. 创建test_case 目录
创建 model 目录
创建 function.py
from selenium import webdriver
import os
import smtplib # 发送邮件模块
from email.mime.text import MIMEText # 定义邮件内容
from email.header import Header # 定义邮件标题
from email.mime.multipart import MIMEMultipart # 附件文件
# 截图
def insert_img(driver,filename):
# 获取模块当前路径
func_path = os.path.dirname(__file__)
# print(func_path)
# 获取上一级目录
base_dir = os.path.dirname(func_path)
# 转为字符串
base_dir = str(base_dir)
# 如果是windows系统路径就解开 windos系统 \\转义 /
# base_dir = base_dir.replace('\\','/')
# 分割为 /home/lbc/PycharmProjects/new_system/simplicity/util/AutoTest_project
base = base_dir.split("/Website")[0]
# 进行拼接 绝对路径
# /home/lbc/PycharmProjects/new_system/simplicity/util/AutoTest_project + /Website/test_report/screenshot + 图片名称.png
filepath = base + "/Website/test_report/screenshot/" + filename
# 进行截图
driver.get_screenshot_as_file(filepath)
# 找出最新时间报告文件
def latest_report(report_dir):
lists = os.listdir(report_dir)
# 按时间顺序对该目录文件夹下面的文件进行排序
lists.sort(key=lambda fn: os.path.getatime(report_dir + '/' + fn))
file = os.path.join(report_dir, lists[-1])
# print(file[12:])
return file
# 邮箱发送
def send_mail(latest_report):
f = open(latest_report,'rb')
mail_content = f.read()
# print(latest_report.file)
# print(mail_content)
f.close()
# 发送邮件
# 发送邮箱服务器
smtpserver = "smtp.qq.com"
# 发送邮箱用户名密码
user = "aaa@qq.com"
# 你的smtp授权码
password = "*****"
# 发送和接收邮箱
sender = "aaa@qq.com"
receive = "aaa@qq.com"
# 多用户发送
# receive = ["aaa@qq.com","aaa@qq.com"]
# 发送邮件主题内容
subject = "自动化测试报告"
# 构造附件内容
# 发送测试报告html文件
send_file = open(latest_report, 'rb').read()
att = MIMEText(send_file, 'base64', 'utf-8')
att["Content-Type"] = 'application/octet-stream'
att["Content-Disposition"] = 'attachment;filename="{}"'.format(latest_report[90:])
# 发送截图快照文件
root_path = '/home/lbc/PycharmProjects/new_system/simplicity/util/AutoTest_project/Website/test_report/screenshot/'
list_path = os.listdir(root_path)
# print(list_path)
wbc = []
for names in enumerate(list_path):
# print(names)
pic_names = '/home/lbc/PycharmProjects/new_system/simplicity/util/AutoTest_project/Website/test_report/screenshot/{}' \
.format(names[1])
send_file2 = open(pic_names, 'rb').read()
att2 = MIMEText(send_file2, 'base64', 'utf-8')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment;filename="{}"'.format(pic_names[101:])
wbc.append(att2)
msgRoot = MIMEMultipart()
msgRoot.attach(MIMEText(mail_content, 'html', 'utf-8'))
msgRoot['Subject'] = Header(subject, 'utf-8')
msgRoot['From'] = "aaa@qq.com"
msgRoot['To'] = receive
# 生成的 快照截图文件
msgRoot.attach(att)
# 遍历 生成的多个图片
for atts2 in wbc:
msgRoot.attach(atts2)
# SSL协议端口号使用456
smtp = smtplib.SMTP_SSL(smtpserver, 465)
# 向服务器标识用户身份
smtp.helo(smtpserver)
# 服务器返回结果确认
smtp.ehlo(smtpserver)
# 登录邮箱账户密码
smtp.login(user, password)
print('开始发送邮件')
smtp.sendmail(sender, receive, msgRoot.as_string())
smtp.quit()
print('邮件发送完成')
# if __name__ == '__main__':
# driver = webdriver.Chrome(
# executable_path='./chromedriver',
# )
# driver.get("http://www.baidu.com")
# insert_img(driver,'baidu.png')
# driver.quit()
创建 myunit.py
import unittest
from driver import *
class StartEnd(unittest.TestCase):
def setUp(self):
self.driver = browser()
print('开始执行')
self.driver.implicitly_wait(3)
self.driver.maximize_window()
def tearDown(self):
self.driver.quit()
print('结束执行')
创建 test_send_png.py(测试文件,生成快照截图路径,与主体项目无关)
import os
root_path = '/home/lbc/PycharmProjects/new_system/simplicity/util/AutoTest_project/Website/test_report/screenshot/'
list_path = os.listdir(root_path)
# print(list_path)
for names in enumerate(list_path):
# print(names)
pic_names = '/home/lbc/PycharmProjects/new_system/simplicity/util/AutoTest_project/Website/test_report/screenshot/{}'\
.format(names[1])
print(pic_names)
# print(len('/home/lbc/PycharmProjects/new_system/simplicity/util/AutoTest_project/Website/test_report/screenshot/'))
abc = open(pic_names,'rb').read()
print(abc)
创建 page_object 目录
创建 BasePage.py
# 设置初始化 传入地址 并比对地址
# 打开指定地址 进行元素检查
from time import sleep
class Page():
def __init__(self,driver):
self.driver = driver
self.base_url = 'https://github.com'
self.timeout = 5
def _open(self,url):
url_ = self.base_url + url
print('Test page is {}'.format(url_))
self.driver.maximize_window()
self.driver.get(url_)
sleep(2)
assert self.driver.current_url == url_ ,'Did not land on {}'.format(url_)
def open(self):
self._open(self.url)
def find_element(self,*loc):
return self.driver.find_element(*loc)
创建 LoginPage.py
# 调用BasePage下的Page类 传入url
# 选择元素进行定位
from Website.test_case.page_object.BasePage import *
from selenium.webdriver.common.by import By
class LoginPage(Page):
# 首页登录页面
url = '/login'
# 定位器
username_loc = (By.NAME,'login')
password_loc = (By.NAME,'password')
submit_loc = (By.NAME,'commit')
# 检查清理元素选择框里的内容
# 用户输入框元素
def type_username(self,username):
self.find_element(*self.username_loc).clear()
self.find_element(*self.username_loc).send_keys(username)
# 用户输入框元素
def type_password(self, password):
self.find_element(*self.password_loc).clear()
self.find_element(*self.password_loc).send_keys(password)
# 登录按钮元素
def type_submit(self):
self.find_element(*self.submit_loc).click()
def Login_action(self,username,password):
self.open()
self.type_username(username)
self.type_password(password)
self.type_submit()
loginPass_loc = (By.LINK_TEXT,'Pull requests')
loginFail_loc = (By.NAME,'login')
def type_loginPass_hint(self):
return self.find_element(*self.loginPass_loc).text
def type_loginFail_hint(self):
return self.find_element(*self.loginFail_loc).text
创建 测试用例,及执行测试用例方法文件
创建 test_login.py
import unittest
from test_case.model import function,myunit
# from test_case.page_object.BasePage import *
from test_case.page_object.LoginPage import *
from time import sleep
class LoginTest(myunit.StartEnd):
# 执行正确的方法
def test_login1_normal(self):
"""username and password is normal"""
print("test_login1_normal is start test...")
po = LoginPage(self.driver)
po.Login_action('aaa@qq.com','123456')
sleep(2)
self.assertEqual(po.type_loginPass_hint(),'Pull requests')
function.insert_img(self.driver,"test_login1_normal.png")
print("test login end!!!")
# 帐号输入正确 密码输入错误
# @unittest.skip("跳过当前")
def test_login2_PasswdError(self):
"""username is ok password is error"""
print("test_login2_PasswdError is start test...")
po = LoginPage(self.driver)
po.Login_action('aaa@qq.com', 'g1346')
sleep(2)
self.assertEqual(po.type_loginFail_hint(), '')
function.insert_img(self.driver, "test_login2_PasswdError.png")
print("test login end!!!")
# 帐号密码都为空
def test_login3_empty(self):
"""username and password is empty"""
print("test_login3_empty is start test...")
po = LoginPage(self.driver)
po.Login_action('', '')
sleep(2)
self.assertEqual(po.type_loginFail_hint(), '')
function.insert_img(self.driver, "test_login3_empty.png")
print("test login end!!!")
if __name__ == '__main__':
unittest.main()
创建 run_test.py
import unittest
from Website.test_case.model.function import *
from BSTestRunner import BSTestRunner
import time
# 执行test*py 用例方法
test_dir = './'
discover = unittest.defaultTestLoader.discover(test_dir, pattern='test*py')
# runner = unittest.TextTestRunner()
# runner.run(discover)
report_dir = '/home/lbc/PycharmProjects/new_system/simplicity/util/AutoTest_project/Website/test_report'
now = time.strftime("%Y-%m-%d %H_%M_%S")
report_name = report_dir + '/' + now +'result.html'
# 生成测试报告
with open(report_name,'wb') as f:
runner = BSTestRunner(stream=f,title="test Report",description="Test case result")
runner.run(discover)
f.close()
# 传递report_dir路径交给 function.py下的latest_report方法 找出最新时间测试报告 并返回 测试报告路径
latest_report = latest_report(report_dir)
# 阅读latest_report路径 打开内容 并将主题 内容 最新测试报告 快照截图文件发送到指定邮箱
send_mail(latest_report)