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()

     

  • 相关阅读:
    Thinking in Java Reading Note(9.接口)
    Thinking in java Reading Note(8.多态)
    Thinking in Java Reading Note(7.复用类)
    SQL必知必会
    Thinking in Java Reading Note(5.初始化与清理)
    Thinking in Java Reading Note(2.一切都是对象)
    鸟哥的Linux私房菜笔记(1.基础)
    Thinking in Java Reading Note(1.对象导论)
    CoreJava2 Reading Note(2:I/O)
    CoreJava2 Reading Note(1:Stream)
  • 原文地址:https://www.cnblogs.com/canghai1024/p/13261367.html
Copyright © 2011-2022 走看看