• PO封装设计模式 -- Web页面端测试


    一、已登录页面 -->新建PO封装的包 -- 以下源码适用于python3以上的版本

     代码优化新增 Image -->对操作步骤进行截图

     二、basepage 包基础类的封装如下:

    from selenium.webdriver.support.wait import WebDriverWait #显示等待
    from selenium.webdriver.support import expected_conditions as EC #判断元素是否定位到

    #页面的基础类 -->为后续类调用

    class HomePage():
    '''构造方法'''
    def __init__(self,url,dr):
    self.url = url
    self.dr = dr

    #封装元素定位方式
    def find_element(self,*loc):
    try:
    #入参本身就是元组 不需要加*
    WebDriverWait(self.dr,10).until(EC.visibility_of_element_located(loc))
    return self.dr.find_element(*loc)
    except:
    print(*loc + '元素定位在页面中无法找到')

    三、page 包封装登录页面的类如下:
    from selenium.webdriver.common.by import By #定位方式
    from time import sleep
    from TestCase.Gjs_Po.basepage.HomePage import *

    #登录页面的类
    class GjsLoginPage(HomePage):
    #定位器
    #输入账号
    username_loc = (By.ID,"mobilePhone")
    # 输入密码
    password_loc = (By.ID,"password")
    # 点击登录按钮
    loginButton_loc = (By.CSS_SELECTOR,"#loginBtn")
    # 登录后验证信息
    loginInfo_loc = (By.CSS_SELECTOR,'#realName')
    # 点击安全登录
    logout_loc = (By.CSS_SELECTOR,"a.fc-blue.mr-5")
    #用户名为空 --获取错误信息
    userNull_loc = (By.CSS_SELECTOR, "span.error")
    #密码为空 --获取错误信息
    passwordNull_loc = (By.CSS_SELECTOR, "span.error")
    #用户名输入非法字符--获取错误信息
    usernameFeifa_loc = (By.CSS_SELECTOR, "span.error")


    #打开登录页面
    def openLoginPage(self):
    self.dr.get(self.url)
    self.dr.refresh()
    self.dr.maximize_window()
    sleep(0.5)

    #输入用户名
    def input_username(self,username):
    #注意 self前面加上 *
    self.find_element(*self.username_loc).send_keys(username)

    #输入密码
    def input_password(self,password):
    self.find_element(*self.password_loc).send_keys(password)

    #点击登录按钮
    def click_btn(self):
    self.find_element(*self.loginButton_loc).click()

    ##登录后验证信息
    def getInfo(self):
    return self.find_element(*self.loginInfo_loc).text

    #点击安全退出
    def logout_btn(self):
    self.find_element(*self.logout_loc).click()

    #用户名为空
    def usernameNull(self):
    return self.find_element(*self.userNull_loc).text

    #密码为空
    def passwordNull(self):
    return self.find_element(*self.passwordNull_loc).text

    #用户名输入非法字符--获取错误信息
    def userFeiFa(self):
    return self.find_element(*self.usernameFeifa_loc).text

    四、common 登录用到的数据封装Helper类 如下:
    import xlrd
    import os
    import logging
    import time

    class Helper(object):

    def readExcels(self,nrow):
    # 读取Excel数据 nrow是输入的行数
    table = xlrd.open_workbook('D:ProjectTestCaseGjs_PodataGjsinfo.xlsx', 'r')
    sheet = table.sheet_by_index(0)
    return sheet.row_values(nrow)

    def readusername(self,nrow):
    # 读取用户名
    return str(self.readExcels(nrow)[0]) # 强制转换为str

    def readpassword(self,nrow):
    # 读取密码
    return str(self.readExcels(nrow)[1])

    def readAssertText(self,nrow):
    # 读取预期结果
    return str(self.readExcels(nrow)[2])

    def dirName(self,filename=None,filePath=None):
    #定义日志文件 filename = log.md 为存储日志
    return os.path.join(os.path.dirname(os.path.dirname(__file__)),filePath,filename)

    def log(self,log_content):
    '''日志定义级别'''
    # 定义文件
    logFile = logging.FileHandler(self.dirName('logInfo.md','log'), 'a',encoding='utf-8')
    # log格式
    fmt = logging.Formatter(fmt='%(asctime)s-%(name)s-%(levelname)s-%(module)s:%(message)s')
    logFile.setFormatter(fmt)

    # 定义日志
    logger1 = logging.Logger('logTest', level=logging.DEBUG)
    logger1.addHandler(logFile)
    logger1.info(log_content)
    logFile.close()

    def SaveImage(self,driver,Filename):
    """用例失败截图"""
    Rawpath = os.path.join(os.path.dirname(os.path.dirname(__file__)),"Image")
    NewPicture = Rawpath + "\" + time.strftime("%Y_%m_%d_%H_%M_%S") + "_" + Filename
    driver.get_screenshot_as_file(NewPicture)

    测试固件分离:
    from selenium import webdriver
    from TestCase.Gjs_Po.page.GjsLoginpage import *
    import unittest

    class MyunitTests(unittest.TestCase):

    def setUp(self)-> None:
    self.url = 'https://www.gjfax.com/toLogin'
    self.dr = webdriver.Chrome()
    self.dr.implicitly_wait(10)

    #实例化一个对象
    self.loginpage = GjsLoginPage(self.url,self.dr)

    def tearDown(self)-> None:
    self.dr.quit()


    五、testCases 测试用例封装,继承unittest、Helper类,如下:
    from TestCase.Gjs_Po.common.helper import *
    from TestCase.Gjs_Po.common.ownUnit import *
    import unittest

    #类的继承
    class GjsTestLogin(MyunitTests,Helper):
    #测试正常的登录
    def test_login_success(self):
    #打开登录页面
    self.loginpage.openLoginPage()
    self.log('测试正常:自动化测试 -->打开登录页面')
    #输入用户名
    self.loginpage.input_username(self.readusername(1))
    self.log('测试正常:自动化测试 -->输入用户名')
    #输入密码
    self.loginpage.input_password(self.readpassword(1))
    self.log('测试正常:自动化测试 -->输入密码')
    #点击登录
    self.loginpage.click_btn()
    self.log('测试正常:自动化测试 -->点击登录')
    #断言
    self.assertEqual(self.loginpage.getInfo(),self.readAssertText(1))
    self.log('测试正常:自动化测试 -->断言登录后信息是否符合预期')
    self.SaveImage(self.dr,"login_success.png")
    #点击退出
    self.loginpage.logout_btn()
    self.log('测试正常:自动化测试 -->点击安全退出')
    self.log('第一条用例执行结束')

    #测试密码为空
    def test_password_null(self):
    # 打开登录页面
    self.loginpage.openLoginPage()
    self.log('测试密码为空:自动化测试 -->点击登录页面')
    # 输入用户名
    self.loginpage.input_username(self.readusername(2))
    self.log('测试密码为空:自动化测试 -->输入用户名')
    # 不输入密码
    self.loginpage.input_password(self.readpassword(2))
    self.log('测试密码为空:自动化测试 -->不输入密码')
    # 点击登录
    self.loginpage.click_btn()
    self.log('测试密码为空:自动化测试 -->点击登录')
    # 断言
    self.assertEqual(self.loginpage.passwordNull(), self.readAssertText(2))
    self.log('测试密码为空:自动化测试 -->断言密码为空信息是否符合预期')
    self.SaveImage(self.dr,"login_passwordNull.png")
    self.log('第二条用例执行结束')

    #测试用户名为空
    def test_username_null(self):
    # 打开登录页面
    self.loginpage.openLoginPage()
    self.log('测试用户名为空:自动化测试 -->点击登录页面')
    # 输入用户名
    self.loginpage.input_username(self.readusername(3))
    self.log('测试用户名为空:自动化测试 -->不输入用户名')
    # 输入密码
    self.loginpage.input_password(self.readpassword(3))
    self.log('测试用户名为空:自动化测试 -->输入密码')
    # 点击登录
    self.loginpage.click_btn()
    self.log('测试用户名为空:自动化测试 -->点击登录')
    # 断言
    self.assertEqual(self.loginpage.usernameNull(), self.readAssertText(3))
    self.log('测试用户名为空:自动化测试 -->断言用户名为空信息是否符合预期')
    self.SaveImage(self.dr,"login_usernameNull.png")
    self.log('第三条用例执行结束')

    #测试用户名输入非法字符
    def test_username_Feifa(self):
    # 打开登录页面
    self.loginpage.openLoginPage()
    self.log('测试用户名输入非法:自动化测试 -->点击登录页面')
    # 输入非法用户名
    self.loginpage.input_username(self.readusername(4))
    self.log('测试用户名输入非法:自动化测试 -->输入非法用户名')
    # 输入密码
    self.loginpage.input_password(self.readpassword(4))
    self.log('测试用户名输入非法:自动化测试 -->输入密码')
    # 点击登录
    self.loginpage.click_btn()
    self.log('测试用户名输入非法:自动化测试 -->点击登录')
    # 断言
    self.assertEqual(self.loginpage.userFeiFa(), self.readAssertText(2))
    self.log('测试用户名输入非法:自动化测试 -->断言用户名输入非法信息是否符合预期')
    self.SaveImage(self.dr,"login_usernameFeifa.png")
    self.log('第四条用例执行结束')

    if __name__ == '__main__':
    unittest.main(verbosity=2)

    六、mail邮件的类封装如下:
    import smtplib
    import os
    from email.mime.multipart import MIMEMultipart #邮件附件类
    from email.mime.text import MIMEText #邮件模板类
    from email.header import Header #邮件头部模板

    #发送带附件的函数
    def semd_mail(file_new):
    with open(file_new, "rb") as fp:
    mail_body = fp.read()

    #基本信息
    smtpserver = "smtp.163.com"
    port = 25
    sender = "1879781xxxx@163.com"
    psw = "qqqxxx" #163邮箱密码
    receiver = "1512500xxx@qq.com"

    #定义邮箱主题
    msg = MIMEMultipart()
    msg['subject'] = Header(u"自动化测试报告","utf-8")
    msg['from'] = sender
    msg["to"] = receiver

    #不加msg['from'] msg["to"]会报错,是因为"收件人和发件人没有定义"
    #HTML 邮件正文,直接发送附件的代码
    body = MIMEText(mail_body,"html","utf-8")
    msg.attach(body)
    # 附件
    att = MIMEText(mail_body,"base64","utf-8")
    att["Content-Type"] = "application/octet-stream"
    att["Content-Disposition"] = 'attachment; filename="test_report.html'
    msg.attach(att)

    #链接邮件服务器发送邮件
    try:
    smtp = smtplib.SMTP()
    smtp.connect(smtpserver) # 连服务器
    smtp.login(sender, psw)
    except:
    smtp = smtplib.SMTP_SSL(smtpserver, port)
    smtp.login(sender, psw) # 登录
    smtp.sendmail(sender, receiver, msg.as_string()) # 发送
    print("邮件发送成功")
    smtp.quit()


    #查找最新的邮件
    def new_file(report_path):
    result_path = report_path
    lists = os.listdir(result_path)
    lists.sort() #从小到大排序
    file = [x for x in lists if x.endswith(".html")]
    file_new_name = os.path.join(result_path,file[-1])
    return file_new_name
    七、runAllcase.py 一键执行测试用例 Main()执行
    from TestCase.Gjs_Po.common.HTMLTestRunner import *
    from TestCase.Gjs_Po.mail.sendmail163 import *
    #实现的逻辑
    #先生成测试报告
    #查找最新的测试报告文件,通过new_file函数找到最新的测试报告,把返回的结果return file_new_name
    #把new_file函数,file_new_name文件传入到send_mail 读取出来,然后以邮件的附件形式加载到邮件模板中,设置参数,链接服务器发送最新的测试报告#


    if __name__ == '__main__':
    report = os.path.dirname(__file__) #D:/Project/TestCase/Gjs_Po
    test_path = os.path.join(report,"testcase") #测试用例文件夹
    suite = unittest.defaultTestLoader.discover(
    start_dir=test_path,pattern="Gjs_login*.py",top_level_dir=None)
    report_path = os.path.join(report,"report") #测试报告文件夹
    if not os.path.exists(report_path):
    os.mkdir(report_path)
    else:
    print('存在report报告文件夹')
    now = time.strftime("%Y-%m-%d %H_%M_%S") #时间戳
    file_name = report_path + '\' + now + "report_test.html" #测试报告文件名
    fp = open(file_name,"wb")
    runner = HTMLTestRunner(
    stream = fp,
    title = 'GJs自动化测试报告',
    description = 'u"系统环境:Windows7 浏览器:Chrome 用例执行情况:"'
    )
    runner.run(suite) #执行测试用例
    fp.close()

    new_report = new_file(report_path) #获取最新的报告文件
    semd_mail(new_report) #发送最新的测试报告

  • 相关阅读:
    Sizzle选择器引擎介绍
    from、includes、indexOf
    indexOf与includes的区别
    ES6 find 和 filter 的区别
    Spring MVC多个视图解析器及优先级
    Spring MVC多个视图解析器及优先级
    freemarker 中文乱码问题解决办法
    freemarker 中文乱码问题解决办法
    freemarker 中文乱码问题解决办法
    Spring集成MyBatis 通用Mapper以及 pagehelper分页插件
  • 原文地址:https://www.cnblogs.com/Teachertao/p/11716531.html
Copyright © 2020-2023  润新知