转载来自:https://www.cnblogs.com/AlwinXu/p/6082920.html

    在写完上一篇“基于Selenium的Web自动化框架”(http://www.cnblogs.com/AlwinXu/p/5836709.html)之后一直没有时间重新审视该框架,正好趁着给同事分享的机会,重新分析了一下框架,发现了很多不足之处,所以才有了这篇增强版。

    到底在框架的哪一部分做了增强呢?这次主要从设计模式的角度来简单介绍一下。
    首先我们来看一下之前是如何书写页面模式中的类的:
    BasePage:

    1. class BasePage(object):
    2. """description of class"""
    3. #webdriver instance
    4. def __init__(self, driver):
    5. self.driver = driver

    GoogleMainPage:

    1. from BasePage import BasePage
    2. from selenium.webdriver.common.by import By
    3. from selenium.webdriver.common.keys import Keys
    4. class GoogleMainPage(BasePage):
    5. """description of class"""
    6. searchbox = (By.ID,'lst-ib')
    7. def inputSearchContent(self,searchContent):
    8. searchBox = self.driver.find_element(*self.searchbox)
    9. searchBox.send_keys(searchContent+Keys.RETURN)

    重新审视之前的实现,我们可以发现在各个子类页面中,均需要引用相当的selenium类库(比如webdriver),并且需要用webdriver来定位页面元素,这就会造成各个子类页面与selenium类库有较多的集成,并且也是书写上的浪费。
    现在来看一下做了结构调整的部分呈现:
    BasePage:

    1. from selenium import webdriver
    2. from selenium.webdriver.common.action_chains import ActionChains
    3. from selenium.common.exceptions import StaleElementReferenceException
    4. from selenium.webdriver.support import expected_conditions as EC
    5. from selenium.webdriver.support.ui import WebDriverWait
    6. from selenium.webdriver.common.by import By
    7. from selenium.webdriver.common.keys import Keys
    8. class BasePage(object):
    9. """description of class"""
    10. #webdriver instance
    11. def __init__(self, browser='chrome'):
    12. '''
    13. initialize selenium webdriver, use chrome as default webdriver
    14. '''
    15. if browser == "firefox" or browser == "ff":
    16. driver = webdriver.Firefox()
    17. elif browser == "chrome":
    18. driver = webdriver.Chrome()
    19. elif browser == "internet explorer" or browser == "ie":
    20. driver = webdriver.Ie()
    21. elif browser == "opera":
    22. driver = webdriver.Opera()
    23. elif browser == "phantomjs":
    24. driver = webdriver.PhantomJS()
    25. try:
    26. self.driver = driver
    27. except Exception:
    28. raise NameError("Not found %s browser,You can enter 'ie', 'ff' or 'chrome'." % browser)
    29. def findElement(self,element):
    30. '''
    31. Find element
    32. element is a set with format (identifier type, value), e.g. ('id','username')
    33. Usage:
    34. self.findElement(element)
    35. '''
    36. try:
    37. type = element[0]
    38. value = element[1]
    39. if type == "id" or type == "ID" or type=="Id":
    40. elem = self.driver.find_element_by_id(value)
    41. elif type == "name" or type == "NAME" or type=="Name":
    42. elem = self.driver.find_element_by_name(value)
    43. elif type == "class" or type == "CLASS" or type=="Class":
    44. elem = self.driver.find_element_by_class_name(value)
    45. elif type == "link_text" or type == "LINK_TEXT" or type=="Link_text":
    46. elem = self.driver.find_element_by_link_text(value)
    47. elif type == "xpath" or type == "XPATH" or type=="Xpath":
    48. elem = self.driver.find_element_by_xpath(value)
    49. elif type == "css" or type == "CSS" or type=="Css":
    50. elem = self.driver.find_element_by_css_selector(value)
    51. else:
    52. raise NameError("Please correct the type in function parameter")
    53. except Exception:
    54. raise ValueError("No such element found"+ str(element))
    55. return elem
    56. def findElements(self,element):
    57. '''
    58. Find elements
    59. element is a set with format (identifier type, value), e.g. ('id','username')
    60. Usage:
    61. self.findElements(element)
    62. '''
    63. try:
    64. type = element[0]
    65. value = element[1]
    66. if type == "id" or type == "ID" or type=="Id":
    67. elem = self.driver.find_elements_by_id(value)
    68. elif type == "name" or type == "NAME" or type=="Name":
    69. elem = self.driver.find_elements_by_name(value)
    70. elif type == "class" or type == "CLASS" or type=="Class":
    71. elem = self.driver.find_elements_by_class_name(value)
    72. elif type == "link_text" or type == "LINK_TEXT" or type=="Link_text":
    73. elem = self.driver.find_elements_by_link_text(value)
    74. elif type == "xpath" or type == "XPATH" or type=="Xpath":
    75. elem = self.driver.find_elements_by_xpath(value)
    76. elif type == "css" or type == "CSS" or type=="Css":
    77. elem = self.driver.find_elements_by_css_selector(value)
    78. else:
    79. raise NameError("Please correct the type in function parameter")
    80. except Exception:
    81. raise ValueError("No such element found"+ str(element))
    82. return elem
    83. def open(self,url):
    84. '''
    85. Open web url
    86. Usage:
    87. self.open(url)
    88. '''
    89. if url != "":
    90. self.driver.get(url)
    91. else:
    92. raise ValueError("please provide a base url")
    93. def type(self,element,text):
    94. '''
    95. Operation input box.
    96. Usage:
    97. self.type(element,text)
    98. '''
    99. element.send_keys(text)
    100. def enter(self,element):
    101. '''
    102. Keyboard: hit return
    103. Usage:
    104. self.enter(element)
    105. '''
    106. element.send_keys(Keys.RETURN)
    107. def click(self,element):
    108. '''
    109. Click page element, like button, image, link, etc.
    110. '''
    111. element.click()
    112. def quit(self):
    113. '''
    114. Quit webdriver
    115. '''
    116. self.driver.quit()
    117. def getAttribute(self, element, attribute):
    118. '''
    119. Get element attribute
    120. '''
    121. return element.get_attribute(attribute)
    122. def getText(self, element):
    123. '''
    124. Get text of a web element
    125. '''
    126. return element.text
    127. def getTitle(self):
    128. '''
    129. Get window title
    130. '''
    131. return self.driver.title
    132. def getCurrentUrl(self):
    133. '''
    134. Get current url
    135. '''
    136. return self.driver.current_url
    137. def getScreenshot(self,targetpath):
    138. '''
    139. Get current screenshot and save it to target path
    140. '''
    141. self.driver.get_screenshot_as_file(targetpath)
    142. def maximizeWindow(self):
    143. '''
    144. Maximize current browser window
    145. '''
    146. self.driver.maximize_window()
    147. def back(self):
    148. '''
    149. Goes one step backward in the browser history.
    150. '''
    151. self.driver.back()
    152. def forward(self):
    153. """
    154. Goes one step forward in the browser history.
    155. """
    156. self.driver.forward()
    157. def getWindowSize(self):
    158. """
    159. Gets the width and height of the current window.
    160. """
    161. return self.driver.get_window_size()
    162. def refresh(self):
    163. '''
    164. Refresh current page
    165. '''
    166. self.driver.refresh()
    167. self.driver.switch_to()

    GoogleMainPage:

    1. from BasePage import BasePage
    2. class GoogleMainPage(BasePage):
    3. """description of class"""
    4. searchbox = ('ID','lst-ib')
    5. def __init__(self, browser = 'chrome'):
    6. super().__init__(browser)
    7. def inputSearchContent(self,searchContent):
    8. searchBox = self.findElement(self.searchbox)
    9. self.type(searchBox,searchContent)
    10. self.enter(searchBox)

    Test
    所做的改变:

    • 将与Selenium类库相关的操作做二次封装,放在BasePage中,其他子类页面自动继承相应的操作方法(如findelement,click等等)
    • 封装了findelement方法,可以根据页面元素的(类型,值)进行查找,只需要调用一个方法findelement(s),而不需要针对不同的类型调用不同的find方法(fine_element_by_xxxx())
    • 子类页面不需要引用selenium的类库,书写更加简单易读
    • 测试用例中也不需要引用selenium的任何类库,简单易读



      代码已更新到GitHub:https://github.com/AlvinXuCH/WebAutomaiton 欢迎提供改进意见