appium+python+unittest+HTMLRunner编写UI自动化测试集
简介
- 获取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': '',
'password': 'qaz123'
},
6 '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):
2 """结束测试"""
3 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):
7 def setUp(self):
8 # 初始化测试平台
self.driver = driver
10 def test_10_admin_login(self):
"""手机登录"""
12 LoginPage(self.driver).PhoneNumberlogin_action(
config.ADMIN_NUMBER,
config.ADMIN_PASSWORD,
15 )
16 def test_16_creat_aquatype(self):
17 """添加水产类型"""
18 PoolPage(self.driver).creat_aquatype(new_aquatype_name)
def test_17_creat_aquatic(self):
20 """养殖池添加养殖"""
PoolPage(self.driver).creat_aquatic()
def test_36_end_testing(self):
"""结束测试"""
24 self.driver.quit()
if __name__ == '__main__':
# 定义一个单元测试容器
27 suite = unittest.TestSuite()
28 # addTest添加case到suite容器中,构造测试集
suite.addTest(SmokeTest('test_10_admin_login'))
30 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):
5 """定位元素"""
6 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()
.......
# 养殖池添加养殖
14 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
7 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):
17 self.find_element() def wait(self, loc):
WebDriverWait(self.driver, 10, 0.005).until(
EC.visibility_of_element_located(loc)
22 ) 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())) # 本地日期作为报告名字
7 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,并生成一份测试报告
18 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')
7 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
appium+python+unittest+HTMLRunner编写UI自动化测试集的更多相关文章
- appium+python 【Mac】UI自动化测试封装框架流程简介 <一>
为了多人之间更方便的协作,那么框架本身的结构和编写方式将变得很重要,因此每个团队都有适合自己的框架.如下本人对APP的UI自动化测试的框架进行进行了简单的汇总.主要目的是为了让团队中的其余人员接手写脚 ...
- python+unittest+requests+HTMLRunner编写接口自动化测试集
问题描述:搭建接口测试框架,执行用例请求多个不同请求方式的接口 实现步骤: ① 创建配置文件config.ini,写入部分公用参数,如接口的基本url.测试报告文件路径.测试数据文件路径等配置项 [D ...
- appium+python 【Mac】UI自动化测试封装框架介绍 <二>---脚本编写(单设备)
1.单设备的执行很简单,平时可多见的是直接在config中进行配置并进行运行即可.如下: # coding=UTF- ''' Created on // @author: SYW ''' from T ...
- appium+python 【Mac】UI自动化测试封装框架介绍 <五>---脚本编写(多设备)
目的: 通过添加设备号,则自动给添加的设备分配端口,启动对应的appium服务.注意:为了方便,将共用一个配置文件. 1.公共的配置文件名称:desired_caps.yaml platformVer ...
- appium+python 【Mac】UI自动化测试封装框架介绍 <七>---脚本编写规范
脚本的使用,注释非常关键,无论自己的后期查看还是别人使用,都可以通过注释很明确的知道代码所表达的意思,明确的知道如何调用方法等等.每个团队均有不同的商定形式来写脚本,因此没有明确的要求和规范来约束.如 ...
- appium+python+unittest+HTMLRunner登录自动化测试报告
环境搭建 python3Java JDK.netFrameworknodejsandroid SDKappiumAppium-Python-Client(pip install Appium-Pyth ...
- appium+python 【Mac】UI自动化测试封装框架介绍 <四>---脚本的调试
优秀的脚本调试定位问题具备的特点: 1.方便调试. 2.运行报错后容易定位出现的问题. 3.日志的记录清晰 4.日志可被存储,一般测试结果的分析在测试之后会进行,那么日志的存储将会为后期的分析问题带来 ...
- appium+python 【Mac】UI自动化测试封装框架介绍 <三>---脚本的执行
我自己编写的脚本框架中,所有的脚本执行均放在一个py文件中,此文件作为启动文件执行,包含了运行此文件将执行脚本.分配设备端口.自启appium服务等. 详细的介绍待后期补充.
- Appium python unittest pageobject如何实现加载多个case
学习了Appium python项目施展的课程小伙伴都会有一个疑问,说现在所有的case都是通过一个suite进行一个方法一个方法进行添加的,但是在实际过程中我们不希望这样,我们做出来的功能是这样: ...
随机推荐
- C# lock 关键字的一些理解
C# lock 关键字的一些理解 问题1:谁是锁? lock 这个关键字,并不是“锁”,真正的“锁”是那个被lock的Object类型的“对象”,请注意,这里为“对象”加了双引号着重强调被lock的是 ...
- python 之 运算符
Python 运算符 Python 运算符 什么是运算符? 本章节主要说明Python的运算符.举个简单的例子 4 +5 = 9 . 例子中,4和5被称为操作数,"+"号为运算 ...
- vs 附加进程 iis进程显示
- GDOI2018D2T1 谈笑风生
T1 谈笑风生 [题目描述] [输入] [输出] 一行两个数,所需能量P与在能量最小的前提下最短的到达时间t. [样例输入] 5 7 66 4 3 2 1 5 1 2 1 5 2 3 2 4 2 5 ...
- jd面试之感
一面问题:问题都回答的很好,顺利进入二面 1.单点登录的改造和原理 2.hashmap 3.jvm:堆.方法区.栈,本地方法栈,gc,gc的方式 4.spring的ioc.aop的实现方式cglib和 ...
- Katana的WebAPI集成Swagger 解决方案
这位大哥写的博客很清楚了,我就不重复了. http://www.cnblogs.com/caodaiming/p/4156476.html 错误解决 http://blog.csdn.net/gold ...
- python爬虫训练——爬poj题目
首先要解决的就是不同的题目在不同的页上,也就是要实现翻页功能,自动获取所要爬取的地址,通过分析可以得出不同的页面也就是volume=后面的数字不同 所以我们可以用re模块来替换即可: new_url ...
- Windows has encountered a critical problem and will restart automatically in one minute. Please save your work now
Windows has encountered a critical problem and will restart automatically in one minute. Please save ...
- _itemmod_description
物品额外描述 表说明: `entry` 物品entry `description` 额外描述
- 【二】php 字符串操作及三大流程控制
字符串操作: trim:去除字符串开始位置和结束位置的空格 ltrim:去除开始处的空格 rtrim:去除结束处的空格 strtoupper:将字符串转换为大写 strtolower:将字符串转换为小 ...