哪里有永久免费建站精美 企业网站模板
简介
- 获取AppPackage和AppActivity
 - 定位UI控件的工具
 - 脚本结构
 - PageObject分层管理
 - HTMLTestRunner生成测试报告
 - 启动appium server服务
 - 以python文件模式执行脚本生成测试报告
 
下载与安装
下载需要自动化测试的App并安装到手机
获取AppPackage和AppActivity
方法一
有源码的情况直接打开AndroidManifest.xml文件,文件会有package信息
android.intent.action.MAIN决定应用程序最先启动的Activity
android.intent.category.LAUNCHER决定应用程序是否显示在程序列表里
方法二
反编译apk,反编译后打开AndroidManifest.xml文件,文件会有package信息
方法三
aapt dump badging F:\****.apk 
aapt工具是sdk自带的一个工具,在sdk\builds-tools\目录下,将appt.exe所在路径添加至path环境变量里,cmd输入aapt查看是否可使用,有如下响应内容即成功

将需要查看的apk复制到电脑任意路径下,例如F:\1.apk
使用命令 aapt dump badging F:\1.apk
运行后的结果前两行分别是包名appPackage和Activity
aapt dump xmltree F:\****.apk AndroidManifest.xml 
方法四
将需要查看的apk复制到电脑任意路径下,例如F:\1.apk
使用命令 aapt dump xmltree F:\1.apk AndroidManifest.xml
运行后的结果就有包名appPackage和Activity

方法五
adb logcat -c //清除logcat内容 adb logcat ActivityManager:I *:s //仅输出标记为“ActivityManager”并且优先级大于等于“Info”的日志,*:S用于设置所有标记的日志优先级为S(无记载,最高优先级,没有什么会被记载) 
手机启动要查看的app,就会加载日志信息
结果如下图:

方法六
adb logcat > D:/logs.txt 或 adb logcat|find "Displayed" >d:/logs.txt 
启动app,cmd输入adb logcat > D:/logs.txt(开启日志),输入Ctrl+C(关闭日志),在日志查找appPackage和AppActivity,文件内搜索Displayed找到Package和Activity信息

或使用该命令直接过滤再保存到txt文件内 adb logcat|find "Displayed" >d:/logs.txt

最终,得到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环境里安装配置
 (自行百度:Pycharm使用python3无法通过HTMLTestRunner生成测试报告)
 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下载集成在代码内
模块下载地址:HTMLTestRunner - tungwaiyip's software
-  
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() 

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什
