BeautifulReport 實現app UI自動化測試
阿新 • • 發佈:2018-12-21
修改了 BeautifulReport原始碼中的一些內容<附:BeautifulReport--適用於unittest自動化測試的視覺化報告>;
1.生成截圖時,原來的img資料夾必須在專案根目錄下,做了調整;
2.生成的截圖無法在html報告上展示,老是會報路徑錯誤,檢查發現原始碼中在做判斷時少加了system()方法才導致錯誤的出現;
原始碼github截圖
修改後截圖
簡單的登入功能實現,懂車帝app為例;
1.頁面元素封裝;
page_car.py
from common.basics importCrazy class CarLoginPage(Crazy): """元素定位""" # 跳過廣告 skip_loc = ('id', 'com.ss.android.auto:id/c8r') def click_skip(self): self.click(self.skip_loc) tag_loc = ("id", "com.ss.android.auto:id/bqp") # 首頁文字 def text_home(self): return self.get_texts(self.tag_loc, 0)# 是否未 登入 def text_landed(self): return self.get_texts(self.tag_loc, 3) # 進入 未登入(我的)頁面 def click_landed(self): self.clicks(self.tag_loc, 3) # # 判斷是否進入未登入(我的)頁 設定 編輯資料 common_loc = ('id', 'com.ss.android.auto:id/dd') def text_common(self): return self.get_text(self.common_loc)# 點選手機圖示 phone_loc = ('id', 'com.ss.android.auto:id/brg') def click_phone(self): self.click(self.phone_loc) # 判斷是否進入手機登入頁面 phone_login_loc = ('id', 'com.ss.android.auto:id/jv') def text_phone_login(self): return self.get_text(self.phone_login_loc) # 輸入手機號 _phone_loc = ('id', 'com.ss.android.auto:id/jy') def input_phone(self, phone): self.send_keys(self._phone_loc, phone) # 點選獲取驗證碼 verification_code_loc = ('id', 'com.ss.android.auto:id/jz') def click_verification_code(self): self.click(self.verification_code_loc) # 輸入驗證碼 input_verification_code_loc = ('id', 'com.ss.android.auto:id/k3') def input_verification(self, code): self.send_keys(self.input_verification_code_loc, code) # 點選 進入app 按鈕 into_btn_loc = ('id', 'com.ss.android.auto:id/k7') def click_into_btn(self): self.click(self.into_btn_loc) # QQ登入 qq_loc = ('id', 'com.ss.android.auto:id/brh') def click_qq(self): self.click(self.qq_loc) # 授權按鈕 # grant_btn_loc = ('id', 'com.tencent.mobileqq:id/name') [36,1418][1044,1538] # grant_btn_loc = [(36, 1301), (1044, 1421)] grant_btn_loc = [(36, 1418), (1044, 1538)] def click_grant_btn(self): self.click_coordinate(self.grant_btn_loc) # 判斷登入成功 personal_center_loc = ('id', 'com.ss.android.auto:id/br3') def text_personal_center(self): return self.get_text(self.personal_center_loc) # 微信登入 wechat_loc = ('id', 'com.ss.android.auto:id/bri') def click_wechat(self): self.click(self.wechat_loc) # 確認登入 [42,1176][1038,1320] com.tencent.mm:id/ch6 [39,1079][1041,1211] [42,1176][1038,1320] confirm_wechat_loc = [(42, 1176), (1038, 1320)] def click_confirm_wechat(self): self.click_coordinate(self.confirm_wechat_loc) # 退出操作 set_up_loc = ('id', 'com.ss.android.auto:id/bvb') def click_set_up(self): self.click(self.set_up_loc) # 判斷進入設定頁 text_common # 退出按鈕 logout_loc = ('id', 'com.ss.android.auto:id/c7o') def click_logout(self): self.click(self.logout_loc) # 是否存在退出按鈕 def element_logout(self): return self.find_element(self.logout_loc) # 退出確認 logout_confirm_loc = ('id', 'com.ss.android.auto:id/i3') def text_logout_confirm(self): return self.get_text(self.logout_confirm_loc) # 確認退出 confirm_logout_loc = ('id', 'com.ss.android.auto:id/c9_') def click_confirm_logout(self): self.click(self.confirm_logout_loc) # 修改資料 update_user_loc = ('id', 'com.ss.android.auto:id/br5') def click_update_user(self): self.click(self.update_user_loc) # 使用者名稱 user_name_loc = ('id', 'com.ss.android.auto:id/j_') def click_user_name(self): self.click(self.user_name_loc) # 請輸入使用者名稱 title enter_user_loc = ('id', 'com.ss.android.auto:id/ali') def text_enter_user(self): return self.get_text(self.enter_user_loc) # 修改使用者名稱 input_user_loc = ('id', 'com.ss.android.auto:id/alj') def input_user(self, name): self.send_keys(self.input_user_loc, name) # 確定按鈕 enter_btn_loc = ('id', 'com.ss.android.auto:id/alm') def click_enter_btn(self): self.click(self.enter_btn_loc) # 獲取使用者名稱稱 get_user_name_loc = ('id', 'com.ss.android.auto:id/jc') def text_get_user_name(self): return self.get_text(self.get_user_name_loc)
basics.py 是用顯示等待封裝的一些常用方法<附:基於顯示等待封裝的一些常用方法>;在做授權操作時,需要使用座標定位的方法實現點選操作;剩下的就是頁面主要元素的函式;
2.測試用例;
test_car.py
import unittest import time from BeautifulReport import BeautifulReport from page.page_car import CarLoginPage from common.logger import Log from common.basics import open_app from common import readConfig class TestCar(unittest.TestCase): @classmethod def setUpClass(cls): cls.driver = open_app() cls.log = Log() cls.car = CarLoginPage(cls.driver) # cls.img_path = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'report\img') cls.img_path = readConfig.img_path # 必須是這個路徑 @classmethod def tearDownClass(cls): cls.driver.close_app() def save_img(self, img_name): self.driver.get_screenshot_as_file('{}/{}.png'.format(self.img_path, img_name)) @BeautifulReport.add_test_img('test_1app') def test_1app(self): """開啟app測試用例""" car = self.car # car.click_skip() # 跳過廣告 self.assertEqual('首頁', car.text_home(), '進入app出錯!') self.log.info('進入app成功!') @BeautifulReport.add_test_img('QQ登入') def test_2qq(self): """QQ登入測試用例""" car = self.car if car.text_landed() == '我的': car.click_landed() self.sign_out() if car.text_landed() == '未登入': self.log.info('使用者未登入,準備 QQ 使用者登入中...') car.click_landed() self.assertEqual(car.text_common(), '常用功能', '未進入 未登入 頁面!') self.log.info('選擇 QQ 使用者登入.') car.click_qq() time.sleep(2) car.click_grant_btn() time.sleep(2) self.assertEqual(car.text_personal_center(), '個人主頁', 'QQ 使用者登入失敗!') self.log.info('QQ 使用者登入成功!') self.save_img('QQ登入') @BeautifulReport.add_test_img('微信登入') def test_2wechat(self): """微信登入測試用例""" car = self.car if car.text_landed() == '我的': car.click_landed() self.sign_out() if car.text_landed() == '未登入': self.log.info('使用者未登入,準備 微信 使用者登入中...') car.click_landed() self.assertEqual(car.text_common(), '常用功能', '未進入 未登入<我的> 頁面!') self.log.info('選擇 微信 使用者登入.') car.click_wechat() time.sleep(2) if car.text_personal_center() == '個人主頁': self.log.info('微信 使用者登入成功!') else: car.click_confirm_wechat() time.sleep(2) self.assertEqual(car.text_personal_center(), '個人主頁', '微信 使用者登入失敗!') self.log.info('微信 使用者登入成功1!') self.save_img('微信登入') @BeautifulReport.add_test_img('編輯資料') def test_4update_user_info(self): """編輯使用者資料""" car = self.car if car.text_landed() == '未登入': self.log.warning('未檢測到使用者登入,不能進行編輯資料操作!') elif car.text_landed() == '我的': self.log.info('使用者已登入,準備進行 編輯資料 操作.') car.click_landed() car.click_update_user() self.assertEqual(car.text_common(), '編輯資料', '出現錯誤,沒有進入 編輯資料 頁面!') start_user = car.text_get_user_name() car.click_user_name() car.input_user('111') car.click_enter_btn() end_user = car.text_get_user_name() self.save_img('編輯資料') time.sleep(2) if start_user == end_user: self.log.info('使用者名稱稱未做修改.') else: self.log.info('修改使用者名稱稱成功!修改後的名稱:{}'.format(end_user)) # def test_3phone(self): # """手機登入""" # car = self.car # if car.text_landed() == '我的': # car.click_landed() # self.sign_out() # if car.text_landed() == '未登入': # self.log.info('使用者未登入,準備 手機 使用者登入中...') # car.click_landed() # self.assertEqual(car.text_common(), '常用功能', '未進入 未登入<我的> 頁面!') # self.log.info('選擇 手機 使用者登入.') # car.click_phone() # self.assertEqual(car.text_phone_login(), '手機快捷登入', '進入 手機快捷登入 頁面失敗!') # car.input_phone('xxxxxxxxxxx') # time.sleep(1) # car.click_verification_code() # time.sleep(2) # car.input_verification('5556') # car.click_into_btn() # self.assertEqual(car.text_personal_center(), '個人主頁', '手機 使用者登入失敗!') # self.log.info('手機 使用者登入成功!') @BeautifulReport.add_test_img('退出登入') def sign_out(self): """使用者退出""" car = self.car if car.text_common() == '常用功能': self.assertEqual(car.text_personal_center(), '個人主頁', '沒有使用者登入,無法退出!') self.log.info('正在執行使用者退出登入操作.') car.click_set_up() self.assertEqual(car.text_common(), '設定', '進入設定頁面失敗!') self.log.info('進入設定頁成功!') car.click_logout() self.assertEqual(car.text_logout_confirm(), '退出確認', '出現錯誤,沒有發現退出確認彈框!') car.click_confirm_logout() if not car.element_logout(): self.log.info('退出登入成功!') self.save_img('退出登入') car.back() else: self.log.info('當前不在 我的 頁面,無法進行退出登入操作!') if __name__ == '__main__': unittest.main()
CarLoginPage,元素類;Log方法,列印日誌<附:python logging模組 輸出日誌和過期清理>;open_app方法,連線appium,啟動被測app;readConfig方法,配置檔案;
手機登入的就比較蛋疼了,試了根據adb logcat獲取手機日誌,提取驗證碼沒有成功...
生成的截圖和html報告:
1.每條用例都會生成一張截圖,錯誤截圖另算;
2.html報告;
錯誤case截圖
正常case截圖