簡介
- 獲取AppPackage和AppActivity
- 定位UI控件的工具
- 腳本結構
- PageObject分層管理
- HTMLTestRunner生成測試報告
- 啟動appium server服務
- 以python文件模式執行腳本生成測試報告
下載與安裝
下載需要自動化測試的App並安裝到手機
獲取AppPackage和AppActivity
參考:https://juejin.im/post/5c3809a451882524c84ebabe
最終,得到App的信息如下:
1 appPackage:com.nbi.aquatic 2 appActivity:.ui.login.LoginActivity
定位UI控件的工具
使用Android SDK的uiautomatorviewer.bat(在..\sdk\tools\ 目錄下),電腦開啟開發者模式,可以使用adb命令的狀態下使用該sdk自帶的工具,可視化安卓手機的界面信息
★ 腳本結構
somke_test.py 存放測試集
config.py 存放自動化測試所用到的數據,如賬號密碼,默認密碼等
pool.py等 測試集中的一個測試用例的page層
base.py 頁面基礎層,供page層繼承
HTMLTestRunner.py 生成測試報告的模塊,可集成到代碼里不需在環境中安裝該模塊,也可在電腦python環境里安裝配置
(參考:https://blog.csdn.net/weixin_38981172/article/details/82389416)
config.py 存放自動化測試所用到的數據,如賬號密碼,默認密碼等
1 settings = { 2 'admin': { 3 'number': '13600000000', 4 'password': 'qaz123' 5 }, 6 'default_password': 'a123456' 7 } 8 ADMIN_NUMBER = settings['admin']['number'] 9 ADMIN_PASSWORD = settings['admin']['password']
啟動app的相關配置傳到appium服務端和連接手機的代碼寫在測試集TestCase外面,如果寫在初始化測試平台的測試用例里則只能啟動執行一次用例
1 desired_caps = {} 2 # Android自動化還是Ios自動化 3 desired_caps['platformName'] = 'Android' 4 # Android操作系統版本 5 desired_caps['platformVersion'] = '5.1' 6 # 設備名稱 7 desired_caps['deviceName'] = '127.0.0.1:62001' 8 # 被測App包名 9 desired_caps['appPackage'] = 'com.nbi.aquatic' 10 # 被測App的入口Activity名 11 desired_caps['appActivity'] = '.ui.login.LoginActivity' 12 desired_caps['automationName'] = 'Uiautomator2' 13 # 把以上配置傳到appium服務端並連接手機 14 driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
啟動app,用到的是unittest自帶的setUp方法
1 def setUp(self): 2 # 初始化測試平台 3 self.driver = driver
關閉app,用到的不是unittest自帶的tearDown方法,而是自定義了一個test_*_end_testing函數,這個函數負責關閉app,是在測試集里的最后一個測試用例
1 def test_36_end_testing(self): 2 """結束測試""" 3 self.driver.quit()
整體測試用例結構,采用PageObject分層管理
1.一個測試用例就是一個函數,后期增加用例時在后面增加新函數即可
2.為了使用unittest框架執行測試集,命名都以test開頭,例如test_16_creat_aquatype
3.每個用例又分獨立的page層,例如測試集里的用例test_16_creat_aquatype,其page層就是PoolPage,在編寫測試集時引入該文件即可,也就是testcase層調用page層
1 from appium import webdriver 2 from test_case.page_object.admin.pool import PoolPage 3 import unittest 4 import config 5 import time 6 class SmokeTest(unittest.TestCase): 7 def setUp(self): 8 # 初始化測試平台 9 self.driver = driver 10 def test_10_admin_login(self): 11 """手機登錄""" 12 LoginPage(self.driver).PhoneNumberlogin_action( 13 config.ADMIN_NUMBER, 14 config.ADMIN_PASSWORD, 15 ) 16 def test_16_creat_aquatype(self): 17 """添加水產類型""" 18 PoolPage(self.driver).creat_aquatype(new_aquatype_name) 19 def test_17_creat_aquatic(self): 20 """養殖池添加養殖""" 21 PoolPage(self.driver).creat_aquatic() 22 def test_36_end_testing(self): 23 """結束測試""" 24 self.driver.quit() 25 if __name__ == '__main__': 26 # 定義一個單元測試容器 27 suite = unittest.TestSuite() 28 # addTest添加case到suite容器中,構造測試集 29 suite.addTest(SmokeTest('test_10_admin_login')) 30 suite.addTest(SmokeTest('test_16_creat_aquatype')) 31 suite.addTest(SmokeTest('test_17_creat_aquatic')) 32 suite.addTest(SmokeTest('test_36_end_testing')) 33 # 執行case 34 runner.run(suite)
4.測試用例test_16_creat_aquatype的page層就是PoolPage,每個page層又都繼承頁面基礎層BasePage
1 from selenium.webdriver.common.by import By 2 from test_case.page_object.base import BasePage 3 import time 4 class PoolPage(BasePage): 5 """定位元素""" 6 creataquatic_btn_loc = (By.ID, 'com.nbi.aquatic:id/tv_add_breed') 7 select_starttime_btn_loc = (By.ID, 'com.nbi.aquatic:id/textView158') 8 # 添加水產類型(水產名稱最長10個字符) 9 def creat_aquatype(self, aquatype_name): 10 time.sleep(3) 11 self.find_element(*self.creataquatic_btn_loc).click() 12 ....... 13 # 養殖池添加養殖 14 def creat_aquatic(self): 15 self.find_element(*self.select_starttime_btn_loc).click()
5.頁面基礎層BasePage
1 from selenium.webdriver.support.ui import WebDriverWait 2 from selenium.webdriver.support import expected_conditions as EC 3 class BasePage(object): 4 """頁面基礎類,用於所有頁面的繼承""" 5 def __init__(self, selenium_driver): 6 self.driver = selenium_driver 7 self.timeout = 30 8 self.poll_frequency = 0.1 9 10 def find_element(self, *loc): 11 return self.driver.find_element(*loc) 12 13 def find_elements(self, *loc): 14 return self.driver.find_elements(*loc) 15 16 def content_appeared(self): 17 self.find_element() 18 19 def wait(self, loc): 20 WebDriverWait(self.driver, 10, 0.005).until( 21 EC.visibility_of_element_located(loc) 22 ) 23 24 def wait_and_compare(self, loc, text): 25 WebDriverWait(self.driver, 30, 0.5).until( 26 EC.text_to_be_present_in_element(loc, text) 27 )
生成HTML測試結果報告
引入方式一,直接電腦python環境安裝HTMLTestRunner模塊
1 import HTMLTestRunner 2 if __name__ == '__main__': 3 suite = unittest.TestSuite() 4 suite.addTest(SmokeTest('test_*_*')) 5 # 寫法一 6 timestr = time.strftime('%Y%m%d', time.localtime(time.time())) # 本地日期作為報告名字 7 filename = 'F:\\folder_data\\' # 文件名字及保存路徑 8 fp = open(filename + (timestr + '.html'), 'wb') 9 runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title='冒煙測試報告', description='用例執行情況: ') 10 11 # 寫法二 12 timestr = time.strftime('%Y%m%d', time.localtime(time.time())) 13 filename = '../_reports/' + timestr + '.html' 14 fp = open(filename, 'wb') 15 runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title='冒煙測試報告', description='用例執行情況: ') 16 17 # 執行case,並生成一份測試報告 18 runner.run(suite) 19 fp.close()
引入方式二,將HTMLTestRunner下載集成在代碼內
模塊下載地址:http://tungwaiyip.info/software/HTMLTestRunner.html
1 from packages.HTMLTestRunner import HTMLTestRunner 2 if __name__ == '__main__': 3 suite = unittest.TestSuite() 4 suite.addTest(SmokeTest('test_*_*')) 5 # 寫法三 6 fp = open('../_reports/result.html', 'wb') 7 runner = HTMLTestRunner(stream=fp, title='冒煙測試報告', description='用例執行情況: ') 8 # 執行case,並生成一份測試報告 9 runner.run(suite) 10 fp.close()
啟動appium server服務
參考:https://juejin.im/post/5c25c6b5f265da612c5df54c
以python文件模式執行腳本生成測試報告
參考:https://juejin.im/post/5c21e4d26fb9a049fd0fdf80