轉-Appium實戰-基類的構建

套用UnitTest構建測試

UnitTest是Python的測試框架,咱們此次的實戰就是基於這個測試框架來構建的,因此就把基類用UnitTest構建起來。css

掃盲,什麼是UnitTest?怎麼用UnitTest?python

  1. 《Hello PyUnitTest》
  2. 《爲你的測試結果打印案例名稱》
  3. 《測試多個類》
  4. 《測試用例的初始化和結束函數》
  5. 《引入其餘類》
  6. 《第一個web自動化》
  7. 《加上測試報告》
  8. 《測試多個文件》

以上是我本身在學習UnitTest過程當中作的一些記錄。android

測試案例的顆粒度必需要細,並且測試一個點以後最好進行環境的還原,所以個人基類是這麼寫的。web

新建一個文件叫BestTestCase,而後輸入下面的代碼:bash

import unittest from appium import webdriver import config class AppTestCase(unittest.TestCase): def setUp(self): desired_caps = { 'platformName': config.CONNECT['platformName'], 'platformVersion': config.CONNECT['platformVersion'], 'deviceName': config.CONNECT['deviceName'], 'appPackage': config.CONNECT['appPackage'], 'appActivity': config.CONNECT['appActivity'] } self.driver = webdriver.Remote(config.CONNECT['baseUrl'], desired_caps) def tearDown(self): self.driver.quit()

這樣寫,只要其餘的測試類來集成這個類就好了,就不用再每一個測試類中寫setUp和tearDown了,並且每次測試完功能點後就會自動退出APP,還原環境。app

導入包有一個import config,這個是我作的一個配置文件,命名爲config.py,我把一些不常修改的參數往這裏丟。好比這個初始化的參數,我就這樣放了。框架

config.py

CONNECT = {
    'platformName': 'Android', 'platformVersion': '4.4.4', 'deviceName': '5136b01e', 'appPackage': 'com.weizq', 'appActivity': 'com.zztzt.android.simple.app.MainActivity', "baseUrl": "http://127.0.0.1:4723/wd/hub" }

構建通用方法

UnitTest的基類構建完以後,咱們要對基礎的方法作一些封裝。函數

經常使用的功能大概有這些:尋找元素的各類方法,系統的按鍵,滑動,獲取座標,截圖等。廢話很少說,先上代碼:學習

from selenium.webdriver.support.expected_conditions import NoSuchElementException from selenium.webdriver.support.ui import WebDriverWait import time as t import config class WebDdriver(object): def __init__(self, driver): self.driver = driver def __str__(self): return 'webDdriver' def find_element(self, *loc): """ 定位元素,定位正確後返回元素的信息,外部調用傳入元組參數必須有*, 例如: find_element(*self.native_caixun) :param loc: 元組類型,結構必須是(By.NAME, u'財訊') :return: element """ try: element = WebDriverWait(self.driver, 10).until(lambda x: x.find_element(*loc)) return element except NoSuchElementException, e: print 'Error details :%s' % (e.args[0]) def find_elements(self, *loc): """ 定位元素,定位正確後返回元素的信息,外部調用傳入元組參數必須有*, 例如: find_elements(*self.native_caixun) :param loc: 元組類型,結構必須是(By.NAME, u'財訊') :return: elements """ try: # return self.driver.find_elements(*loc) elements = WebDriverWait(self.driver, 10).until(lambda x: x.find_elements(*loc)) return elements except NoSuchElementException, e: print 'Error details :%s' % (e.args[0]) def get_title(self): """ 獲取頁面的標題 :return: str, 頁面的標題 """ title = self.find_elements(*config.COMMON['view_title'])[0].text return title @property def wait(self): t.sleep(5) def getScreenshot(self, name, url, form='png'): t.sleep(2) self.driver.get_screenshot_as_file(url + name + "." + form) def sysback(self): """ 系統的返回按鈕 :return: None """ self.driver.keyevent(4) def get_size(self): """ 獲取當前屏幕的分辨率 :return: int, x*y """ size = self.driver.get_window_size() return size def swipe_to_up(self): """ 從下往上滑動 :return: None """ window_size = self.get_size() width = window_size.get("width") height = window_size.get("height") self.driver.swipe(width / 2, height * 3 / 4, width / 2, height / 4, 500) def swipe_to_down(self): """ 從上往下滑動 :return: None """ window_size = self.get_size() width = window_size.get("width") height = window_size.get("height") self.driver.swipe(width / 2, height / 4, width / 2, height * 3 / 4, 500) def swipe_to_left(self): """ 從右往左滑動 :return: None """ window_size = self.get_size() width = window_size.get("width") height = window_size.get("height") self.driver.swipe(width / 4, height / 2, width * 3 / 4, height / 2, 500) def swipe_to_right(self): """ 從左往右滑動 :return: None """ window_size = self.get_size() width = window_size.get("width") height = window_size.get("height") self.driver.swipe(width * 4 / 5, height / 2, width / 5, height / 2, 500) def getLocation(self, *loc): """ 獲取元素的定位信息,外部調用傳入元組參數必須有*, 例如: (*self.native_caixun) :param loc: 元素的定位方式 :return: list, [x, y] """ locaX = self.find_element(*loc).location.get('x') locaY = self.find_element(*loc).location.get('y') rst = [locaX, locaY] return rst

註釋我應該寫的很清楚了,就把一些比較重要的地方作一些解釋,在init中先把剛剛構建的driver初始化了,讓類中的其餘方法可使用driver。測試

兩個最重要的方法,find_element和find_elements作一下重點說明。正常來講,找元素的方法有這麼幾種,name、id、xpath、tag、class_name、link_text等,可是若是作這麼多封裝,代碼就會顯得很是多,固然,若是沒有其餘辦法的話,那就只能老老實實的枚舉了,可是若是去看webdriver的源碼,就能找到這麼一個方法。源碼是這樣的:

class By(object): """ Set of supported locator strategies. """ ID = "id" XPATH = "xpath" LINK_TEXT = "link text" PARTIAL_LINK_TEXT = "partial link text" NAME = "name" TAG_NAME = "tag name" CLASS_NAME = "class name" CSS_SELECTOR = "css selector" @classmethod def is_valid(cls, by): for attr in dir(cls): if by == getattr(cls, attr): return True return False

那麼也就是說,在webdriver的方法源碼中已經幫咱們枚舉了,那麼咱們就能夠直接調用這個方法,,作參數傳入就好了。方法有作入參檢查,所以傳入參數要求是tuple的類型,因此元素我就所有剝離出來用配置文件處理,配置文件的內容咱們就這樣寫:

from selenium.webdriver.common.by import By CAIXUN = { 'tuijian': (By.NAME, u'推薦'), 'gupiao': (By.NAME, u'股票'), 'jijin': (By.NAME, u'基金'), 'zhaiquan': (By.NAME, u'債券'), 'xinsanban': (By.NAME, u'新三板'), 'zixunneirong': (By.ID, 'com.weizq:id/new_title'), # 財訊記錄列表,用find_elements調用 'imgurl': '/Users/SvenWeng/PycharmProjects/WeStock/img/caixun/', 'title': [ ['tuijian', 'tuijianneirong'], ['gupiao', 'gupiaoneirong'], ['jijin', 'jijinneirong'], ['zhaiquan', 'zhaiquanneirong'], ['xinsanban', 'xinsanbanneirong'] ], 'jiahao': (By.CLASS_NAME, 'android.widget.ImageView'), 'pindao': (By.ID, 'com.weizq:id/text_item'), }

中間的那些元素就直接這樣配置,若是開發進行了一些修改,那麼咱們就直接改這裏就好了。這就是Page Object最大的好處了。

最後

最底層的構建就先這樣處理了。固然還有其餘方法須要構建,好比某個頁面的元素定位方法。已經方法的調用。

相關文章
相關標籤/搜索