简介
* 获取AppPackage和AppActivity
* 定位UI控件的工具
* 脚本结构
* PageObject分层管理
* HTMLTestRunner生成测试报告
* 启动appium server服务
* 以python文件模式执行脚本生成测试报告
>**下载与安装
下载需要自动化测试的App并安装到手机
>**获取AppPackage和AppActivity**
参考:https://juejin.im/post/5c3809a451882524c84ebabe
最终,得到App的信息如下:
```
appPackage:com.nbi.aquatic
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 存放自动化测试所用到的数据,如账号密码,默认密码等**
```
settings = {
'admin': {
'number': '13600000000',
'password': 'qaz123'
},
'default_password': 'a123456'
}
ADMIN_NUMBER = settings['admin']['number']
ADMIN_PASSWORD = settings['admin']['password']
```
**启动app的相关配置传到appium服务端和连接手机的代码写在测试集TestCase外面,如果写在初始化测试平台的测试用例里则只能启动执行一次用例**
```
desired_caps = {}
# Android自动化还是Ios自动化
desired_caps['platformName'] = 'Android'
# Android操作系统版本
desired_caps['platformVersion'] = '5.1'
# 设备名称
desired_caps['deviceName'] = '127.0.0.1:62001'
# 被测App包名
desired_caps['appPackage'] = 'com.nbi.aquatic'
# 被测App的入口Activity名
desired_caps['appActivity'] = '.ui.login.LoginActivity'
desired_caps['automationName'] = 'Uiautomator2'
# 把以上配置传到appium服务端并连接手机
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
```
**启动app,用到的是unittest自带的setUp方法**
```
def setUp(self):
# 初始化测试平台
self.driver = driver
```
**关闭app,用到的不是unittest自带的tearDown方法,而是自定义了一个test_*_end_testing函数,这个函数负责关闭app,是在测试集里的最后一个测试用例**
```
def test_36_end_testing(self):
"""结束测试"""
self.driver.quit()
```
>**整体测试用例结构,采用PageObject分层管理**
1.一个测试用例就是一个函数,后期增加用例时在后面增加新函数即可
2.为了使用unittest框架执行测试集,命名都以test开头,例如test_16_creat_aquatype
3.每个用例又分独立的page层,例如测试集里的用例test_16_creat_aquatype,其page层就是PoolPage,在编写测试集时引入该文件即可,也就是testcase层调用page层
```
from appium import webdriver
from test_case.page_object.admin.pool import PoolPage
import unittest
import config
import time
class SmokeTest(unittest.TestCase):
def setUp(self):
# 初始化测试平台
self.driver = driver
def test_10_admin_login(self):
"""手机登录"""
LoginPage(self.driver).PhoneNumberlogin_action(
config.ADMIN_NUMBER,
config.ADMIN_PASSWORD,
)
def test_16_creat_aquatype(self):
"""添加水产类型"""
PoolPage(self.driver).creat_aquatype(new_aquatype_name)
def test_17_creat_aquatic(self):
"""养殖池添加养殖"""
PoolPage(self.driver).creat_aquatic()
def test_36_end_testing(self):
"""结束测试"""
self.driver.quit()
if __name__ == '__main__':
# 定义一个单元测试容器
suite = unittest.TestSuite()
# addTest添加case到suite容器中,构造测试集
suite.addTest(SmokeTest('test_10_admin_login'))
suite.addTest(SmokeTest('test_16_creat_aquatype'))
suite.addTest(SmokeTest('test_17_creat_aquatic'))
suite.addTest(SmokeTest('test_36_end_testing'))
# 执行case
runner.run(suite)
```
4.测试用例test_16_creat_aquatype的page层就是PoolPage,每个page层又都继承页面基础层BasePage
```
from selenium.webdriver.common.by import By
from test_case.page_object.base import BasePage
import time
class PoolPage(BasePage):
"""定位元素"""
creataquatic_btn_loc = (By.ID, 'com.nbi.aquatic:id/tv_add_breed')
select_starttime_btn_loc = (By.ID, 'com.nbi.aquatic:id/textView158')
# 添加水产类型(水产名称最长10个字符)
def creat_aquatype(self, aquatype_name):
time.sleep(3)
self.find_element(*self.creataquatic_btn_loc).click()
.......
# 养殖池添加养殖
def creat_aquatic(self):
self.find_element(*self.select_starttime_btn_loc).click()
```
5.页面基础层BasePage
```
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class BasePage(object):
"""页面基础类,用于所有页面的继承"""
def __init__(self, selenium_driver):
self.driver = selenium_driver
self.timeout = 30
self.poll_frequency = 0.1
def find_element(self, *loc):
return self.driver.find_element(*loc)
def find_elements(self, *loc):
return self.driver.find_elements(*loc)
def content_appeared(self):
self.find_element()
def wait(self, loc):
WebDriverWait(self.driver, 10, 0.005).until(
EC.visibility_of_element_located(loc)
)
def wait_and_compare(self, loc, text):
WebDriverWait(self.driver, 30, 0.5).until(
EC.text_to_be_present_in_element(loc, text)
)
```
>**生成HTML测试结果报告**
引入方式一,直接电脑python环境安装HTMLTestRunner模块
```
import HTMLTestRunner
if __name__ == '__main__':
suite = unittest.TestSuite()
suite.addTest(SmokeTest('test_*_*'))
# 写法一
timestr = time.strftime('%Y%m%d', time.localtime(time.time())) # 本地日期作为报告名字
filename = 'F:\\folder_data\\' # 文件名字及保存路径
fp = open(filename + (timestr + '.html'), 'wb')
runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title='冒烟测试报告', description='用例执行情况: ')
# 写法二
timestr = time.strftime('%Y%m%d', time.localtime(time.time()))
filename = '../_reports/' + timestr + '.html'
fp = open(filename, 'wb')
runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title='冒烟测试报告', description='用例执行情况: ')
# 执行case,并生成一份测试报告
runner.run(suite)
fp.close()
```
引入方式二,将HTMLTestRunner下载集成在代码内
模块下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html
```
from packages.HTMLTestRunner import HTMLTestRunner
if __name__ == '__main__':
suite = unittest.TestSuite()
suite.addTest(SmokeTest('test_*_*'))
# 写法三
fp = open('../_reports/result.html', 'wb')
runner = HTMLTestRunner(stream=fp, title='冒烟测试报告', description='用例执行情况: ')
# 执行case,并生成一份测试报告
runner.run(suite)
fp.close()
```
>**启动appium server服务**
参考:https://juejin.im/post/5c25c6b5f265da612c5df54c
>**以python文件模式执行脚本生成测试报告**
参考:https://juejin.im/post/5c21e4d26fb9a049fd0fdf80
文摘归档
- 2019年02月(1016)
- 2019年01月(1698)
- 2016年10月(1)
- 2016年09月(11)
- 2016年07月(43)
- 2016年06月(37)
- 2016年05月(77)
- 2016年04月(62)
- 2016年03月(32)
- 2016年02月(4)
- 2016年01月(10)
- 2015年12月(3)
- 2015年11月(6)
- 2015年10月(8)
- 2015年09月(14)
- 2015年08月(453)
- 2015年07月(41)
- 2015年06月(36)
- 2015年05月(44)
- 2015年04月(46)
- 2015年03月(51)
- 2015年02月(24)
- 2015年01月(45)
- 2014年12月(34)
- 2014年11月(40)
- 2014年10月(56)
- 2014年09月(52)
- 2014年08月(66)
- 2014年07月(55)
- 2014年06月(83)
- 2014年05月(79)
- 2014年04月(64)
- 2014年03月(48)
- 2014年02月(46)
- 2014年01月(28)
- 2013年12月(63)
- 2013年11月(77)
- 2013年10月(72)
- 2013年09月(62)
- 2013年08月(83)
- 2013年07月(60)
- 2013年06月(21)
阅读排行榜
- Cocos2D-x之开发环境配置 (4689)
- TLS 协议所定义的严重错误代码是 10。Windows SChannel 错误状态是 1203 (3753)
- UART和RS232、RS485的基础知识 (3493)
- 本地文件数据加载到hive (3261)
- WAS8.0与IHS集群安装与配置指导手册 (3021)
- C/C++常见编译链接错误解决方法 (2419)
- 如何重定向Keepalived日志的输出路径 (2278)
- devstack安装报错解决方法:pkg_resources.DistributionNotFound: pip==1.4.1 (1480)
- HAProxy 研究笔记 -- HTTP请求处理-2-解析 (1206)
- iOS项目开发实战——Swift实现多个TableView的侧滑与切换 (1060)