zoukankan      html  css  js  c++  java
  • selenium自动化简易测试框架总结

    一、目录结构

    Base目录:公共、基础的方法和类

    logs:日志文件

    PageObject:每个页面元素的定位、操作方法封装

    report:测试报告

    UniTest:测试用例编写以及执行

    二、各部分的示例代码

    Base/base_page.py:所有页面都需要用到的方法

    from
    selenium import webdriver import time import os #定义所有页面都需要的基础类 class BasePage(): #初始化操作,获取浏览器驱动、地址 def __init__(self,driver,url): self.driver = driver self.url = url #打开浏览器,访问页面 def open(self): self.driver.get(self.url) self.driver.maximize_window() #定位页面元素 def locator_element(self,*locator): el = self.driver.find_element(*locator) return el #退出浏览器 def quit(self): self.driver.quit() #定义截图函数 def insert_images(self,file_name): base_dir = os.path.dirname(os.path.dirname(__file__)) file_path = os.path.join(base_dir + '/','report/images/') self.driver.get_screenshot_as_file(file_path+file_name) #获取用例执行时时间 def get_current_time(self): return time.strftime('%Y-%m-%d-%H-%M-%S',time.localtime()) if __name__ == '__main__': path = os.path.dirname(os.path.dirname(__file__)) file_path = os.path.join(path + '/','report/images/','test.html') print(path) print(file_path)

    log.py:日志操作方法

    import logging
    import os
    import time
    
    
    class OptionLog():
        def __init__(self):
            #创建logger实例
            self.logger = logging.getLogger()
            #设置logger输出级别
            self.logger.setLevel(logging.INFO)
            #设置日志输出格式
            formatter = logging.Formatter('%(asctime)s-%(module)s-%(funcName)s:%(message)s')
    
            #按照日期创建日志文件
            base_dir = os.path.dirname(os.path.dirname(__file__)) + '/'
            file_path = os.path.join(base_dir,'logs')
            current_data = time.strftime('%Y-%m-%d',time.localtime())
            file_name = file_path + '/' + current_data + '.log'
    
            #日志保存到文件
            self.file_handler = logging.FileHandler(file_name,'a',encoding='utf-8')
            self.file_handler.setFormatter(formatter)
    
            #日志输出到控制台
            self.consele_handler = logging.StreamHandler()
            self.consele_handler.formatter = formatter
    
            #为logger添加日志处理器
            self.logger.addHandler(self.file_handler)
            self.logger.addHandler(self.consele_handler)
    
        def get_logger(self):
            return self.logger
    
        def close_handle(self):
            #移除日志句柄
            self.logger.removeHandler(self.file_handler)
            self.logger.removeHandler(self.consele_handler)
            #关闭日志处理器
            self.file_handler.close()
            self.consele_handler.close()
    
    
    if __name__ == '__main__':
        myLog = OptionLog()
        logger = myLog.get_logger()
        print(logger)
        logger.info('测试日志输出')
        myLog.close_handle()

    send_email.py:发送邮件方法封装

    import os
    import time
    import smtplib
    from email.utils import formataddr
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    from email.header import Header
    
    from Base import BASE_DIR
    from Base.log import OptionLog
    
    class SendEmail():
        def __init__(self,sender,pwd,recevier,content='这是测试报告,请领导查阅',subject='selenium测试报告'):
            self.sender = sender #发件人邮箱账号
            self.pwd = pwd #发件人邮箱密码
            self.receiver = recevier #接收者
            self.content = content #发送的邮件内容
            self.subject = subject #邮件主题
    
        def send(self):
            """"
            发送最新测试报告
            """
            #找出最新的测试报告
            file_path = os.path.join(BASE_DIR ,'report\html\')
            last_file = self.find_latest_file(file_path)
            last_file_name = os.path.basename(last_file)
    
            #实例化日志对象
            logger = OptionLog().get_logger()
    
            #组织邮件附件
            try:
                sendfile = open(last_file, 'r', encoding='utf-8').read()
                msg = MIMEText(sendfile, 'base64', 'utf-8')
                msg['Content-Type'] = 'application/octet-sream'
                msg['Content-Disposition'] = "attachment;filename =%s "%last_file_name
                msg['Subject'] = 'selenium测试报告'
                msg['TO'] = ','.join(self.receiver) #当接收者是多人的时候,需要传字符串,否则会报错
    
                #组织邮件正文信息
                msgRoot = MIMEMultipart('related')
                msgRoot['Subject'] = self.subject
                content = MIMEText(self.content.encode(),'plain', 'utf-8')
    
                #添加正文、附件
                msgRoot.attach(msg)
                msgRoot.attach(content)
    
                #登录qq邮件服务器发送邮件
                s = smtplib.SMTP_SSL('smtp.qq.com', 465)
                s.login(self.sender, self.pwd)
                s.sendmail(self.sender, self.receiver, msgRoot.as_string())
    
                #记录成功日志
                logger.info('测试报告发送成功')
    
            except Exception as e:
                logger.info(str(e))
    
        #找出目录下最新创建的文件
        def find_latest_file(self,file_path):
            files = os.listdir(file_path)
            files.sort(key=lambda file:os.stat(file_path+file).st_ctime )
            latest_file = files[-1]
            latest_file_path = os.path.join(file_path,latest_file)
            return latest_file_path
    
    
    if __name__ == '__main__':
        email_obj = SendEmail('xxxxx@qq.com','xxxxxxxxx',['xxxxxxxx@qq.com','xxxxxxxx@qq.com'])
        res = email_obj.send()

    login_page.py:登录页面对象封装

    from Base.base_page import BasePage
    from selenium.webdriver.common.by import By
    from selenium import webdriver
    
    
    class LoginPage(BasePage):
        accout_id = (By.ID,'userAccount')
        password_id = (By.ID,'password')
        login_xpath = (By.CLASS_NAME,'ant-btn')
    
        #输入用户名
        def input_account(self,account):
            self.locator_element(*self.accout_id).send_keys(account)
    
        #输入密码
        def input_password(self,pwd):
            self.locator_element(*self.password_id).send_keys(pwd)
    
        #点击登录
        def click_login_ele(self):
            self.locator_element(*self.login_xpath).click()
    
        user_empty_hit = (By.XPATH,'//*[@id="root"]/div/div/div[2]/form/div[1]/div/div[2]/div')
        pwd_empty_hit = (By.XPATH,'//*[@id="root"]/div/div/div[2]/form/div[2]/div/div[2]/div')
        user_pwd_error_hit = (By.XPATH,'/html/body/div[2]/div/span/div/div/div/span[2]')
        #用户名或密码错误提示
        def user_pwd_error_msg(self):
            return self.locator_element(*self.user_pwd_error_hit).text
    
        #用户名为空提示
        def user_empty_msg(self):
            return self.locator_element(*self.user_empty_hit).text
    
        #密码为空提示
        def pwd_empty_msg(self):
            return self.locator_element(*self.pwd_empty_hit).text
    
        #登录流程
        def login(self,account,pwd):
            self.open()
            self.input_account(account)
            self.input_password(pwd)
            self.click_login_ele()
    
    if __name__ == '__main__':
        driver = webdriver.Chrome()
        url = 'http://xxxxxx.com/login'
        login_page = LoginPage(driver,url)
        login_page.login('22222','333333')
        import time
        time.sleep(3)
        login_page.user_pwd_error_msg()

    test_case.py:测试用例封装

    import time
    import unittest
    from ddt import data,ddt,unpack
    from selenium import webdriver
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    
    from PageObject.login_page import LoginPage
    from Base.log import OptionLog
    
    
    @ddt
    class TestLogin(unittest.TestCase):
        @classmethod
        def setUpClass(cls):
            cls.log = OptionLog()
            cls.logger = cls.log.get_logger()
    
        @classmethod
        def tearDownClass(cls):
            cls.log.close_handle()
        def setUp(self):
            self.driver = webdriver.Chrome()
            self.driver.implicitly_wait(10)
    
        def tearDown(self):
            time.sleep(5)
            self.driver.quit()
    
        @data(('http://xxxxxx.com/login','xxxxxxxx','123456'))
        @unpack
        def test_login1(self,url,account,pwd):
            """用户名、密码正确"""
            self.logger.info('用户名、密码正确')
            login_page = LoginPage(self.driver,url)
            login_page.login(account,pwd)
            title = self.driver.title
            time.sleep(5)
            #判断登录后页面标题
            page_title = EC.title_contains("地图慧")(self.driver)
            #判断页面左下角登录账号昵称
            user_name = EC.presence_of_element_located((By.XPATH,'//*[@id="superNav"]/div/footer/div[2]/span[2]'))(self.driver)
            user_name1 = EC.visibility_of_element_located((By.XPATH,'//*[@id="superNav"]/div/footer/div[2]/span[2]'))(self.driver)
            self.assertEqual(True,page_title)
            self.assertNotEqual(False,user_name1)
    
            #用例执行完后截图
            login_page.insert_images(login_page.get_current_time() + '(用户名、密码正确).png')
    
    
        @data(('http://xxxxxxx.com/login', 'xxxxxxxx', '111111'))
        @unpack
        def test_login2(self,url,account,pwd):
            """用户名、密码错误"""
            self.logger.info('用户名、密码错误')
            login_page = LoginPage(self.driver,url)
            login_page.login(account,pwd)
            time.sleep(3)
            self.assertEqual(login_page.user_pwd_error_msg(),'账号或密码错误!')
    
            # 用例执行完后截图
            login_page.insert_images(login_page.get_current_time() + '(用户名、密码错误).png')
    
        @data((('http://xxxxxxx.com/login', '', '111111')))
        @unpack
        def test_login3(self,url,account,pwd):
            """用户名为空,密码正确"""
            self.logger.info('用户名为空,密码正确"')
            login_page = LoginPage(self.driver, url)
            login_page.login(account, pwd)
            time.sleep(3)
            self.assertEqual(login_page.user_empty_msg(), '请输入手机号')
    
            # 用例执行完后截图
            login_page.insert_images(login_page.get_current_time() + '(用户名为空,密码正确).png')
    
        @data((('http://xxxxxxx.com/login', 'xxxxxxxx', '')))
        @unpack
        def test_login4(self,url,account,pwd):
            """用户名正确,密码为空"""
            self.logger.info('用户名正确,密码为空')
            login_page = LoginPage(self.driver, url)
            login_page.login(account, pwd)
            time.sleep(3)
            self.assertEqual(login_page.pwd_empty_msg(), '密码不能为空')
    
            # 用例执行完后截图
            login_page.insert_images(login_page.get_current_time() + '(用户名正确,密码为空).png')
    
    if __name__ == '__main__':
        unittest.main()

    run_case.py:测试用例的执行

    import os
    import time
    
    import unittest
    from HTMLTestRunner import HTMLTestRunner
    
    from Base import BASE_DIR
    from Base.send_email import SendEmail
    
    def run_all_case():
        #查找指定目录下的用例文件
        discover = unittest.defaultTestLoader.discover('./','test_*.py',top_level_dir=None)
        # runner = unittest.TextTestRunner()
    
        #按照用例执行时间命名生成测试报告
        current_time  = time.strftime('%Y-%m-%d-%H-%M-%S',time.localtime())
        report_path = os.path.join(BASE_DIR+'/report/html/'+ current_time + 'result.html')
    
        with open(report_path,'wb') as fp:
            runner = HTMLTestRunner(stream=fp)
            runner.run(discover)
    
        #用例执行完后发送测试报告
        email_obj = SendEmail('xxxxxx@qq.com', 'xxxxxxx', ['xxxxxxx@qq.com', 'xxxxxxxxx@qq.com'])
        email_obj.send()
    
    if __name__ == '__main__':
        run_all_case()

     

  • 相关阅读:
    AllowsTransparency和WebBrowser兼容性问题解决方案
    webbrowser和js交互小结
    wpf数据验证实例及常用方法小结
    Scrum 冲刺第一天
    Scrum 冲刺第二天
    1625 宝石项链 大视野评测
    1082栅栏 大视野评测
    bzoj 1606: [Usaco2008 Dec]Hay For Sale 购买干草
    1639 月度开支 大视野评测
    1650 跳石子 大视野评测
  • 原文地址:https://www.cnblogs.com/Xiaojiangzi/p/13261367.html
Copyright © 2011-2022 走看看