zoukankan      html  css  js  c++  java
  • Selenium自动化Page模式(Python)

    Selenium是当前主流的web自动化工具,提供了多种浏览器的支持(Chrome,Firefox, IE等等),当然大家也可以用自己喜欢的语言(Java,C#,Python等)来写用例,很容易上手。当大家写完第一个自动化用例的时候肯定感觉”哇...好牛x“,但是大家用余光扫了一下代码后,内心也许是崩溃的,因为太乱了!像这样:

    __author__ = 'xua'
    
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    import unittest
    
    class TCRepeatLogin(unittest.TestCase):
        def setUp(self):
    
            #webdriver
            self.driver = webdriver.Chrome(r'C:UsersxuaDownloadschromedriver_win32chromedriver.exe')
            self.driver.implicitly_wait(30)
            self.base_url = "http://10.222.30.145:9000/"
    
        def test_(self):
            driver = self.driver
            driver.get(self.base_url)
    
            #enter username and password
            driver.find_element_by_id("username").clear()
            driver.find_element_by_id("username").send_keys("sbxadmin")
            driver.find_element_by_id("password").clear()
            driver.find_element_by_id("password").send_keys("IGTtest1"+Keys.RETURN)
    
            #find dialog and check
            dialogTitle = driver.find_element(By.XPATH,'//html/body/div[7]/div/div/div[1]/h3')
            self.assertEqual("Sign in",dialogTitle.text)
    
            #find cancel button and click
            cancelBtn = driver.find_element(By.XPATH,'//html/body/div[7]/div/div/div[3]/button[2]')
            cancelBtn.click()
    
        def tearDown(self):
            self.driver.close()
    
    if __name__ == "__main__":
        unittest.main()

    从几点来分析下上边的代码:

    1. 易读性:非常难理解。这么多find element?这难道也是test case?

    2. 可扩展性:都是一个个孤立的test case,无扩展性可言

    3. 可复用性:无公共方法,很难提到复用

    4. 可维护性:一旦页面元素修改,则需要相应修改所有相关用例,effort大

    基于以上的问题,Python为我们提供了Page模式来管理测试,它大概是这样子的:(TestCase中的虚线箭头应该是指向各个page,家里电脑没装修改软件,就不改了:))

    关于Page模式:

    1. 抽象出来一个BasePage基类,它包含一个指向Selenium.webdriver的属性

    2. 每一个webpage都继承自BasePage基类,通过driver来获取本页面的元素,每个页面的操作都抽象为一个个方法

    3. TestCase继承自unittest.Testcase类,并依赖相应的Page类来实现相应的test case步骤

    利用Page模式实现上边的用例,代码如下:

    BasePage.py:

    __author__ = 'xua'
    
    from selenium.webdriver.common.by import By
    from selenium.webdriver.common.keys import Keys
    
    
    #super class
    class BasePage(object):
        def __init__(self, driver):
            self.driver = driver
    
    class LoginPage(BasePage): #page element identifier usename = (By.ID,'username') password = (By.ID, 'password') dialogTitle = (By.XPATH,'//html/body/div[7]/div/div/div[1]/h3') cancelButton = (By.XPATH,'//html/body/div[7]/div/div/div[3]/button[2]') #Get username textbox and input username def set_username(self,username): name = self.driver.find_element(*LoginPage.usename) name.send_keys(username) #Get password textbox and input password, then hit return def set_password(self, password): pwd = self.driver.find_element(*LoginPage.password) pwd.send_keys(password + Keys.RETURN) #Get pop up dialog title def get_DiaglogTitle(self): digTitle = self.driver.find_element(*LoginPage.dialogTitle) return digTitle.text #Get "cancel" button and then click def click_cancel(self): cancelbtn = self.driver.find_element(*LoginPage.cancelButton) cancelbtn.click()

     Test_Login.py:

    __author__ = 'xua'
    
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.common.alert import Alert
    import unittest
    import time
    import BasePage
    
    class Test_Login(unittest.TestCase):
    
        #Setup
        def setUp(self):
            self.driver = webdriver.Chrome(r'C:UsersxuaDownloadschromedriver_win32chromedriver.exe')
            self.driver.implicitly_wait(30)
            self.base_url = "http://10.222.30.145:9000/"
        #tearDown
        def tearDown(self):
            self.driver.close()
    
        def test_Login(self):
            #Step1: open base site
            self.driver.get(self.base_url)
            #Step2: Open Login page
            login_page = BasePage.LoginPage(self.driver)
            #Step3: Enter username
            login_page.set_username("sbXadmin")
            #Step4: Enter password
            login_page.set_password("IGTtest1")
            #Checkpoint1: Check popup dialog title
            self.assertEqual(login_page.get_DiaglogTitle(),"Sign in")
            #Step5: Cancel dialog
            login_page.click_cancel()
    
    
    if __name__ == "__main__":
        unittest.main()

    Ok, 那么我们回头来看,Page模式是否解决了上边的四个方面的问题:

    1. 易读性: 现在单看test_login方法,确实有点test case的样子了,每一步都很明了

    2. 可扩展性:由于把每个page的元素操作都集成到一个page类中,所以增删改查都和方便

    3. 可复用性: page的基本操作都变成了一个个的方法,在不同的test case中可以重复使用

    4. 可维护性:如果页面修改,只需修改相应page类中的方法即可,无需修改每个test case

    总结:

    Page模式给我们提供了一个很好的页面和用例实现的分离机制,降低了耦合,提高了内聚,可以使我们在web自动化中做到游刃有余。

  • 相关阅读:
    YARN源码学习(七)-----Task级别GC相关指标的自定义counter添加
    YARN源码学习(七)-----Task级别GC相关指标的自定义counter添加
    YARN源码分析(八)-----Reduce Shuffle过程分析
    YARN源码分析(八)-----Reduce Shuffle过程分析
    【每天一道算法题】整数循环节之和——数字黑洞6174
    getline函数
    设计模式之建造者模式Builder(创建型)
    字符串算法总结
    C++设计模式之单例模式
    Linux下C的线程同步机制
  • 原文地址:https://www.cnblogs.com/AlwinXu/p/5537955.html
Copyright © 2011-2022 走看看