欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python自动化Selenium单元测试page object设计模式框架设计流程

程序员文章站 2022-04-10 17:05:05
...

本文章将Selenium单元测试page object设计模式框架表述完整流程

本章来测试,github登录小功能

设计架构:

Python自动化Selenium单元测试page object设计模式框架设计流程

目录结构:

Python自动化Selenium单元测试page object设计模式框架设计流程

代码流程描述:

1. 创建AutoTest_project 主目录

Python自动化Selenium单元测试page object设计模式框架设计流程

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)

4. 创建test_report 目录
这个目录负责存储 测试数据 测试报告 快照截图

Python自动化Selenium单元测试page object设计模式框架设计流程

找到 run_test.py 运行整套项目

Python自动化Selenium单元测试page object设计模式框架设计流程

邮箱结果

Python自动化Selenium单元测试page object设计模式框架设计流程
Python自动化Selenium单元测试page object设计模式框架设计流程

大功告成!!!

相关标签: Unittest