轉-Appium—驅動和經常使用功能的封裝

driver的封裝

初始化的driver是Python操做Appium的核心,所以driver在整個代碼中重用率是很是高的。python

新建一個driver.py文件,專門用來封裝driver。代碼以下:android

# ecoding=utf-8 __author__ = "Sven_Weng" from appium import webdriver class AppiumTest: def __init__(self): desired_caps = {'platformName': 'Android', 'platformVersion': '5.0.2', 'deviceName': '5136b01e', 'appPackage': 'com.weizq', 'appActivity': 'com.zztzt.android.simple.app.MainActivity'} self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) self.driver.implicitly_wait(30) def get_driver(self): return self.driver

在AppiumTest這個類中,初始化函數包含了driver的信息,而後在get_driver函數中直接把這個driver返回回去,測試用例中只要在測試類的初始化中調用它,就能獲取driver。web

按模塊劃分封裝的方法

我是這麼劃分模塊的,一個Element,專門封裝操做和對象有關的方法,把find_element_by_id這種很長很長的方法縮短一點,用一些比較簡潔的名字封裝一下,使用起來代碼可讀性也會比較強。一個common類,專門封裝通用的方法,其餘就是按照功能模塊來劃分,我測試的微證券有4個主要功能,因此會有財訊、行情、發現、我這些類模塊。json

element對象封裝

我本身的代碼以下:app

class Element: """ 封裝Appium中關於元素對象的方法 """ def __init__(self): at = AppiumTest() self.driver = at.get_driver() def get_id(self, id): element = self.driver.find_element_by_id(id) return element def get_name(self, name): element = self.driver.find_element_by_name(name) return element def over(self): element = self.driver.quit() return element def get_screen(self, path): self.driver.get_screenshot_as_file(path) def get_size(self): size = self.driver.get_window_size() return size def swipe_to_up(self): 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): 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): 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): 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 back(self): self.driver.keyevent(4) def get_classes(self, classesname): elements = self.driver.find_elements_by_class_name(classesname) return elements def get_ids(self, ids): elements = self.driver.find_elements_by_id(ids) return elements def switch_h5(self): self.driver.execute(MobileCommand.SWITCH_TO_CONTEXT, {"name": "WEBVIEW_com.weizq"}) def switch_app(self): self.driver.execute(MobileCommand.SWITCH_TO_CONTEXT, {"name": "NATIVE_APP"})

上面封裝的很簡單,就是一些經常使用的方法,在初始化函數中初始化driver便可。函數

common

common就是封裝一些通用的方法,好比登陸,比大小,獲取股票代碼,頁面標題校驗等等。如下是個人代碼:測試

class Common: """ 封裝通用的方法 """ def __init__(self): self.cf = ConfigParser.ConfigParser() self.cf.read('enable_data.conf') def cycle_screen(self, section_name, num, driver): """ 循環截圖功能 從json文件中讀取信息,用來定位點擊的方位和保存截圖的路徑 執行成功則返回True,不然返回False :param section_name: json文件中一級節點的名稱 :param num: json文件中對應的列表序列位 :param driver: Appium的驅動 :return:True or False """ try: with open('get_screen.json', 'r') as f: jsondata = f.read() cx_info = json.loads(jsondata) values = cx_info[section_name][num].values() for value in values: driver.get_name(value['name']).click() time.sleep(2) self.check_title(value['name'], driver) driver.get_screen(value['path']) logging.info(value['log']) return True except Exception as e: logging.warning(e) return False def cycle_screen_and_back(self, section_name, num, driver): """ 功能和上一個函數同樣,在步驟最後加了一個返回事件,用來處理"行情"-"更多"頁面的數據校驗 :param section_name: conf配置文件的節點名稱 """ try: with open('get_screen.json', 'r') as f: jsondata = f.read() cx_info = json.loads(jsondata) values = cx_info[section_name][num].values() for value in values: logging.info(value) driver.get_name(value['name']).click() time.sleep(2) self.check_title(value['name'], driver) # title = driver.get_classes('android.widget.TextView')[0].text # try: # assert title == value['name'] # logging.info(title + '頁面顯示正確') # except Exception as e: # logging.warning(value['name']) # logging.warning(title + '頁面顯示不正確') driver.get_screen(value['path']) driver.driver.keyevent(4) time.sleep(1) logging.info(value['log']) return True except Exception as e: logging.warning(e) return False def check_title(self, title, driver): text = driver.get_classes('android.widget.TextView')[0].text try: assert text == title logging.info("標題爲: {} 校驗經過".format(title)) return True except Exception as e: logging.warning(e) logging.warning("標題爲: {} 校驗不經過".format(title)) return False def compare(self, ids, numstar, numend, driver): """ 比較傳入值得大小, 第一個數比第二個數大返回True,不然返回False :param ids:傳入的ID名 :param numstar:傳入的開始序號 :param numend:傳入的結束須要 :param driver:驅動 :return:True or False """ try: startext = float(driver.get_ids(ids)[numstar].text) endtext = float(driver.get_ids(ids)[numend].text) except ValueError: starmark = driver.get_ids(ids)[numstar].text[:1] endmark = driver.get_ids(ids)[numend].text[:1] if starmark == endmark: startext = float(driver.get_ids(ids)[numstar].text.lstrip(starmark).rstrip('%')) endtext = float(driver.get_ids(ids)[numend].text.lstrip(endmark).rstrip('%')) elif starmark == "+": return True elif starmark == "-": return False if startext > endtext: return True else: return False def get_SotckCode(self, ids, driver): """ 獲取行情-自選頁面中的全部股票代碼,自選超過50支的時候請修改參數中的range(10) 返回list :param driver:驅動控件 :return:list, 自選股票代碼 """ SotckCode = [] for x in driver.get_ids(ids): SotckCode.append(x.text) for x in range(5): driver.swipe_to_up() for x in driver.get_ids(ids): if x.text not in SotckCode: SotckCode.append(x.text) return SotckCode def zjzh_login(self, driver): """ 資金帳號登陸方法,傳入appium-driver APP啓動時須要資金帳號爲登陸狀態時調用 :param driver: Appium驅動 :return: True """ driver.get_name('發現').click() driver.switch_h5() driver.get_classes('list-item')[1].click() driver.switch_app() driver.get_name('買入').click() username = self.cf.get('zjzh_login_info', 'username') password = self.cf.get('zjzh_login_info', 'password') if self.tra_login(username, password, driver): self.check_title(u'委託買入', driver) driver.back() driver.back() self.check_title(u'發現', driver) logging.info('資金帳號登陸成功') return True def tra_login(self, username, password, driver): """ 資金帳號登陸頁面的登陸方法 :param username:帳號 :param password:密碼 :param driver:Appium驅動 :return:True """ driver.get_id('com.weizq:id/edit_account').clear() driver.get_id('com.weizq:id/edit_account').send_keys(username) logging.info('輸入的帳號爲: {}'.format(username)) driver.get_id('com.weizq:id/edit_password').send_keys(password) logging.info('輸入的密碼爲: {}'.format(password)) yzm = driver.get_id('com.weizq:id/text_yanzhengma').text logging.info('驗證碼爲:{}'.format(yzm)) driver.get_id('com.weizq:id/edit_yanzhengma').send_keys(yzm) driver.get_id('com.weizq:id/login').click() time.sleep(3) return True

其餘功能模塊

其餘功能模塊也是一樣的道理,不過其餘模塊封裝的都是特定功能模塊纔會用到的方法,由於代碼可能涉及公司的機密,因此功能模塊的代碼就暫不放出來,思想仍是同樣的。ui

日誌記錄

關於日誌記錄的原則,我以爲是這樣的,寫入日誌的必須是一些關鍵的信息,把日誌瀏覽一遍,基本上就能瞭解到整個腳本跑的流程,好比我調試一些功能的時候,基本上不用關注手機運行的頁面,腳本到底作了什麼,只要看日誌就懂了。下面是一些我調試功能的時候打出來的日誌:spa

Thu, 24 Mar 2016 14:26:35 test_weizq.py[line:437] INFO ==========結束測試個人內容==========調試

Thu, 24 Mar 2016 14:26:37 test_weizq.py[line:429] INFO ==========開始測試個人內容==========

Thu, 24 Mar 2016 14:26:55 test_weizq.py[line:429] INFO ==========開始測試個人內容==========

Thu, 24 Mar 2016 14:27:23 test_weizq.py[line:429] INFO ==========開始測試個人內容==========

Thu, 24 Mar 2016 14:27:32 test_weizq.py[line:448] INFO —–開始測試我的資料頁面校驗—–

Thu, 24 Mar 2016 14:27:36 test_weizq.py[line:456] INFO 舊的暱稱是: 6850252

Thu, 24 Mar 2016 14:27:50 test_weizq.py[line:463] INFO 新的暱稱是: 5030013

Thu, 24 Mar 2016 14:27:50 test_weizq.py[line:437] INFO ==========結束測試個人內容==========

Thu, 24 Mar 2016 14:31:55 test_weizq.py[line:429] INFO ==========開始測試個人內容==========

Thu, 24 Mar 2016 14:32:06 test_weizq.py[line:448] INFO —–開始測試我的資料頁面校驗—–

Thu, 24 Mar 2016 14:32:09 test_weizq.py[line:468] INFO 女

Thu, 24 Mar 2016 14:32:09 test_weizq.py[line:437] INFO ==========結束測試個人內容==========

Thu, 24 Mar 2016 14:34:38 test_weizq.py[line:429] INFO ==========開始測試個人內容==========

Thu, 24 Mar 2016 14:34:50 test_weizq.py[line:448] INFO —–開始測試我的資料頁面校驗—–

Thu, 24 Mar 2016 14:34:53 test_weizq.py[line:468] INFO 修改前的性別: 女

Thu, 24 Mar 2016 14:34:58 test_weizq.py[line:472] INFO 性別修改成: 男

Thu, 24 Mar 2016 14:34:58 test_weizq.py[line:437] INFO ==========結束測試個人內容==========

Thu, 24 Mar 2016 14:35:14 test_weizq.py[line:429] INFO ==========開始測試個人內容==========

Thu, 24 Mar 2016 14:35:35 test_weizq.py[line:429] INFO ==========開始測試個人內容==========

Thu, 24 Mar 2016 14:35:47 test_weizq.py[line:429] INFO ==========開始測試個人內容==========

Thu, 24 Mar 2016 14:36:01 test_weizq.py[line:429] INFO ==========開始測試個人內容==========

Thu, 24 Mar 2016 14:36:12 test_weizq.py[line:448] INFO —–開始測試我的資料頁面校驗—–

Thu, 24 Mar 2016 14:36:16 test_weizq.py[line:456] INFO 舊的暱稱是: 5030013

Thu, 24 Mar 2016 14:36:28 test_weizq.py[line:463] INFO 新的暱稱是: 908602

Thu, 24 Mar 2016 14:36:28 test_weizq.py[line:468] INFO 修改前的性別: 男

Thu, 24 Mar 2016 14:36:33 test_weizq.py[line:475] INFO 性別修改成: 女

Thu, 24 Mar 2016 14:36:33 test_weizq.py[line:437] INFO ==========結束測試個人內容==========

基本上看到這些日誌就知道我到底在測試什麼東西了。

相關文章
相關標籤/搜索