• Page Object设计模式实践


    Page Object是Selenium自动化测试项目开发实践的最佳设计模式之一,通过对界面元素的封装减少冗余代码,同时在后期维护中,若元素定位发生变化,只需要调整页面元素封装的代码,提高测试用例的可维护性。

      本项目以163邮箱登录为例,163登录脚本(非PO模式)请查看博客中的随笔信息。

    1、项目目录结构及相关介绍

    test_programe 测试项目

    • driver:用于存放驱动
    • mail:用于存放163登录项目的测试用例、测试报告以及测试数据等
    • run_all_test.py:用于运行项目自动化用例

    mail目录

    • data:存放测试数据
    • report:存放HTML测试不报告,其中该目录下的image目录用于存放测试过程中的截图
    • test_case:用于存放测试用例

    test_case目录

    • model:存放配置函数及公共类
    • page_object:用于存放页面对象
    • login_case.py:测试对象用例

    2、编写公共模块:

    编写驱动文件... est_programemail est_casemodeldriver.py

    复制代码
     1 from selenium.webdriver import Remote
     2 from selenium import webdriver
     3 #启动浏览器驱动
     4 def browser():
     5     driver = webdriver.Chrome()
     6     '''
     7     #可以启动到远程主机中,运行自动化测试
     8     host = '127.0.0.1:4444' #运行主机:端口号(本机默认:127.0.0.1:4444)
     9     dc = {'browserName': 'chrome'}  #指定浏览器
    10     driver = Remote(command_execute='http://' + host + '/wd/hub',
    11                     desired_capabilities=dc)
    12     '''
    13     return driver
    14 '''
    15 #用于测试该脚本是否有效
    16 if __name__ == '__main__':
    17     dr = browser()
    18 '''
    复制代码

    编写测试公共类... est_programemail est_casemodelmyunit.py

    复制代码
    from time import sleep
    from .function import insert_img
    import unittest
    from .driver import browser
    
    
    class MyTest(unittest.TestCase):
    
    
        def setUp(self):
            self.driver = browser()
            self.driver.implicitly_wait(10)
            self.driver.maximize_window()
    
    
        def tearDown(self):
            self.driver.quit()
    复制代码

     定义截图函数... est_programemail est_casemodelfunction.py

    复制代码
     1 from selenium import webdriver
     2 import os
     3 #截图函数
     4 def insert_img(driver, file_name):
     5     base_dir = os.path.dirname(os.path.dirname(__file__))
     6     #print(base_dir)
     7     base_dir = str(base_dir)
     8     #print(base_dir)
     9     base_dir = base_dir.replace('\','/')
    10     #print(base_dir)
    11     base = base_dir.split('/mail')[0]
    12     #print(base)
    13     file_path = base + '/mail/report/image/' + file_name
    14     driver.get_screenshot_as_file(file_path)
    15 
    16 '''
    17 #用于验证该脚本是否有效
    18 if __name__ == '__main__':
    19     driver = webdriver.Chrome()
    20     driver.get('http://www.baidu.com')
    21     insert_img(driver, 'baidu.jpg')
    22     driver.quit()
    23 '''
    复制代码

    3、编写Page Object

    创建基础类... est_programemail est_casepage_objectase.py

    复制代码
     1 from selenium import webdriver
     2 from selenium.webdriver.common.by import By
     3 from time import sleep
     4 import unittest
     5 #基本层
     6 class Base(object):
     7 
     8     
     9     def __init__(self, driver, base_url = 'http://mail.163.com'):
    10         self.driver = driver
    11         self.base_url = base_url
    12         self.timeout = 30
    13 
    14     def _open(self, url):
    15         url_ = self.base_url + url
    16         #print(url_)
    17         self.driver.maximize_window()
    18         self.driver.get(url_)
    19         sleep(2)
    20         assert self.driver.current_url == url_, 'Did ont land on %s' % url_
    21 
    22     def open(self):
    23         self._open(self.url)
    24 
    25     #*参数个数不是固定的(By.ID, 'kw')
    26     def find_element(self, *loc):
    27         return self.driver.find_element(*loc)
    28 
    29     def iframe(self, iframeid):
    30         return self.driver.switch_to.frame(iframeid)
    31 
    32     def iframe_out(self):
    33         return self.driver.switch_to.default_content()
    34 
    35     
    复制代码

    创建163邮箱登录对象类... est_programemail est_casepage_objectlogin_page.py

    复制代码
     1 from selenium.webdriver.common.action_chains import ActionChains
     2 from selenium.webdriver.common.by import By
     3 from time import sleep
     4 from .base import Base
     5 
     6 #页面对象(PO)登录页面
     7 class LoginPage(Base):
     8     url = '/'
     9     login_iframe_loc = 'x-URS-iframe'
    10     login_username_text_loc = (By.NAME, 'email')
    11     login_password_text_loc = (By.NAME, 'password')
    12     login_button_loc = (By.ID, 'dologin')
    13     login_erro_hint_loc = (By.CLASS_NAME, 'ferrorhead')
    14 
    15     #把每一个元素封装成一个方法
    16     def login_iframe(self):
    17         self.iframe(self.login_iframe_loc)
    18 
    19     def login_iframe_out(self):
    20         self.iframe_out()
    21 
    22     def login_username(self, text):
    23         self.find_element(*self.login_username_text_loc).send_keys(text)
    24 
    25     def login_password(self, text):
    26         self.find_element(*self.login_password_text_loc).send_keys(text)
    27 
    28     def login_button(self):
    29         self.find_element(*self.login_button_loc).click()
    30 
    31     def login_error_hint(self):
    32         self.login_iframe()
    33         return self.find_element(*self.login_erro_hint_loc).text
    34         self.login_iframe_out()
    35 
    36     def login_action(self, username, password):
    37         self.login_iframe()
    38         self.login_username(username)
    39         self.login_password(password)
    40         self.login_button()
    41         self.login_iframe_out()
    复制代码

    创建163邮箱登录成功后对象类... est_programemail est_casepage_objectmail_page.py

    复制代码
     1 from selenium.webdriver.common.action_chains import ActionChains
     2 from selenium.webdriver.common.by import By
     3 from time import sleep
     4 from .base import Base
     5 
     6 class MailPage(Base):
     7     url = '/'
     8     login_success_user_loc = (By.ID, 'spnUid')
     9 
    10     def login_success_user(self):
    11         return self.find_element(*self.login_success_user_loc).text
    复制代码

    4、编写测试用例

    创建mail登录类... est_programemail est_caselogin_case.py

    复制代码
     1 from time import sleep
     2 import unittest, random, sys
     3 from model import myunit, function
     4 from page_object.login_page import LoginPage
     5 from page_object.mail_page import MailPage
     6 sys.path.append('./model')
     7 sys.path.append('./page_obj')
     8 
     9 class LoginTest(myunit.MyTest):
    10 
    11     def test_login_user_pwd_null(self):
    12         '''用户名、密码为空登录'''
    13         po = LoginPage(self.driver)
    14         po.open()
    15         po.login_action('','')
    16         sleep(2)
    17         self.assertEqual(po.login_error_hint(),'请输入帐号')
    18         function.insert_img(self.driver, 'user_pwd_null.jpg')
    19 
    20     def test_login_pwd_null(self):
    21         '''密码为空登录'''
    22         po = LoginPage(self.driver)
    23         po.open()
    24         po.login_action('abc','')
    25         sleep(2)
    26         self.assertEqual(po.login_error_hint(),'请输入密码')
    27         function.insert_img(self.driver, 'pwd_null.jpg')
    28 
    29     def test_login_user_pwd_error(self):
    30         '''用户名或密码错误'''
    31         po = LoginPage(self.driver)
    32         po.open()
    33         character = random.choice('zyxwvutsrqponmlkjihgfedcba')
    34         username = "test" + character
    35         po.login_action(username,"$#%#")
    36         sleep(2)
    37         #print(po.login_error_hint())
    38         self.assertEqual(po.login_error_hint(),'帐号或密码错误')
    39         function.insert_img(self.driver, "user_pwd_error.jpg")
    40 
    41     def test_login_success(self):
    42         '''用户名、密码正确,登录成功'''
    43         po = LoginPage(self.driver)
    44         po.open()
    45         user = "ldq791918813"
    46         po.login_action(user,"xiuxiu060801zhu")
    47         sleep(2)
    48         po2 = MailPage(self.driver)
    49         #print(po2.login_success_user())
    50         self.assertEqual(po2.login_success_user(),user+"@163.com")
    51         function.insert_img(self.driver, "success.jpg")
    复制代码

    5、执行测试用例

    创建用例执行代码... est_programe

    复制代码
     1 import unittest, time
     2 from HTMLTestRunner import HTMLTestRunner
     3 from email.mime.text import MIMEText
     4 from email.header import Header
     5 import smtplib, os
     6 
     7 #发送测试报告,需要配置你的邮箱账号
     8 def send_mail(file_new):
     9     f = open(file_new, 'rb')
    10     mail_body = f.read()
    11     f.close()
    12     msg = MIMEText(mail_body, 'html', 'utf-8')
    13     msg['Subject'] = Header("自动化测试报告", 'utf-8')
    14     msg['From']= 'ldq791918813@163.com'
    15     msg['To']= '791918813@qq.com'
    16     smtp = smtplib.SMTP()
    17     smtp.connect("smtp.163.com")
    18     smtp.login("ldq791918813@163.com", "密码")
    19     smtp.sendmail("ldq791918813@163.com","791918813@qq.com",msg.as_string())
    20     smtp.quit()
    21     print('email has send out!')
    22 
    23 #查找测试报告目录,找到最新生成的测试报告文件
    24 def new_report(testreport):
    25     lists = os.listdir(testreport)
    26     lists.sort(key=lambda fn: os.path.getmtime(testreport + '\' + fn))
    27     file_new = os.path.join(testreport, lists[-1])
    28     print(file_new)
    29     return file_new
    30 
    31 #指定测试用例为当前文件夹下的test_case目录
    32 test_dir = './mail/test_case'
    33 test_report = 'D:\sublimePython\test_programe\mail\report'
    34 discover = unittest.defaultTestLoader.discover(test_dir, pattern = '*_case.py')
    35 
    36 if __name__ == "__main__":
    37     
    38     now = time.strftime("%Y-%m-%d %H_%M_%S")
    39     filename = test_report + '/' + now + 'result.html'
    40     fp = open(filename, 'wb')
    41     #runner = unittest.TextTestRunner()
    42     runner = HTMLTestRunner(stream=fp,
    43                             title='测试报告',
    44                             description="运行环境:windows 7, Chrome")
    45     runner.run(discover)
    46     fp.close()
    47     
    48     new_report = new_report(test_report)
    49     send_mail(new_report)
    复制代码

    6、HTML测试报告:

    7、截图信息:

  • 相关阅读:
    js将单个反斜杠转化为斜杠的问题
    HTML提供的6种空格
    JavaScript 内存管理
    JavaScript:4个常见的内存泄露
    正则多种匹配描述
    css3图片展示方式
    动态规划篇一:初见动态规划
    小球下落(Dropping Balls, Uva 679)
    破损的键盘(悲剧文本)(Broken Keyboard(a.k.a. Beiju Text),Uva 11988)
    铁轨(rails, ACM/ICPC CERC 1997,Uva 514)
  • 原文地址:https://www.cnblogs.com/111testing/p/7103978.html
Copyright © 2020-2023  润新知