【UI自动化测试】Appium+Python+Unittest+HTMLRunner
简介
- 获取AppPackage和AppActivity
- 定位UI控件的工具
- 脚本结构
- PageObject分层管理
- HTMLTestRunner生成测试报告
- 启动appium server服务
- 以python文件模式执行脚本生成测试报告
【B站最通俗易懂】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 webdriver2 from test_case.page_object.admin.pool import PoolPage3 import unittest4 import config5 import time6 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 By2 from test_case.page_object.base import BasePage3 import time4 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 WebDriverWait2 from selenium.webdriver.support import expected_conditions as EC3 class BasePage(object):4 """页面基础类,用于所有页面的继承"""5 def __init__(self, selenium_driver):6 self.driver = selenium_driver7 self.timeout = 308 self.poll_frequency = 0.19
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 HTMLTestRunner2 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 HTMLTestRunner2 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()
相关文章:

【UI自动化测试】Appium+Python+Unittest+HTMLRunner
简介 获取AppPackage和AppActivity 定位UI控件的工具 脚本结构 PageObject分层管理 HTMLTestRunner生成测试报告 启动appium server服务 以python文件模式执行脚本生成测试报告 【B站最通俗易懂】Python接口自动化测试从入门到精通,超详细的进阶教程,看完…...

【限时优惠】红帽openstack管理课程(CL210) 即将开课
课程介绍 通过实验室操作练习,学员将能够深入学习红帽企业 Linux OpenStack 平台各服务的手动安装方法,还将了解 OpenStack 开发社区的未来发展计划。 培训地点: 线下面授:苏州市姑苏区干将东路666号401室; 远程…...

Golang之路---02 基础语法——函数
函数 函数定义 func function_name( [parameter list] ) [return_types] {函数体 }参数解释: func:函数由 func 开始声明function_name:函数名称,函数名和参数列表一起构成了函数签名。[parameter list]:参数列表&a…...

数据结构和算法入门(时间/空间复杂度介绍--java版)
数据结构和算法入门(时间/空间复杂度介绍–java版) write in front 作者: 向大佬学习 专栏: 数据结构(java版) 作者简介:大二学生 希望能学习其同学和大佬的经验! 本篇博客简介&…...
Spring Mvc 文件上传(MultipartFile )—官方原版
一、创建应用程序类 要启动Spring Boot MVC应用程序,首先需要一个启动器。在这个示例中,已经添加了spring-boot-starter thymelaf和spring-boot-starter web作为依赖项。要使用Servlet容器上传文件,您需要注册一个MultipartConfigElement类&…...
【E题】2023年电赛运动目标控制与自动追踪系统方案
系统的设计和制作可以按照以下步骤进行: 设计红色光斑位置控制系统: 选择合适的红色激光笔,并将其固定在一个二维电控云台上。 使用电机和编码器来控制电控云台的水平和垂直运动。 设计一个控制电路,可以通过输入控制信号来控制…...
企业网络安全之零信任和身份认证
零信任并不是一种技术,而是一个安全概念,是一种建立安全战略的理念、方法和框架。 零信任提供了一系列概念和思想,其中心思想是怀疑一切,否定一切,不再以网络边界为限,不能再将内部网络定义为可信任的&…...

【雕爷学编程】MicroPython动手做(28)——物联网之Yeelight 5
知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…...
[运维|中间件] 东方通TongWeb使用笔记
参考文献 东方通tongweb部署服务 东方通tongweb部署服务 使用笔记 默认访问地址 http://ip:9060/console/默认用户名密码 TongWeb7.0默认用户名密码:thanos,thanos123.com...

WIZnet W6100-EVB-Pico DHCP 配置教程(三)
前言 在上一章节中我们讲了网络信息配置,那些网络信息的配置都是用户手动的去配置的,为了能跟电脑处于同一网段,且电脑能成功ping通板子,我们不仅要注意子网掩码,对于IP地址主机位和网络位的划分,而且还要注…...
【Linux】Ansible 脚本 playbook 剧本
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 Ansible 脚本 playbook 剧本 playbook 剧本Templates 模块tags 模块Roles 模块在一个 playbook 中使用 roles 的步骤 playbook 剧本 playbooks 本身由以下各部分组成 &#…...

解决 tensorflow 出现的 ImportError: Could not find the DLL(s) ‘msvcp140_1.dll‘. 问题
在安装完tensorflow库后出现 问题详述: ImportError: Could not find the DLL(s) msvcp140_1.dll. TensorFlow requires that these DLLs be installed in a directory that is named in your %PATH% environment variable. You may install these DLLs by downlo…...

百度与AI:历史、投资和监管
来源:猛兽财经 作者:猛兽财经 百度的人工智能在中国具有先发优势 随着ChatGPT的爆火,人工智能重新引起了投资者的注意,然而人工智能并不是突然爆火的,而是全球众多公司在人工智能技术上进行数十年如一日的研发和积累&a…...

Kafka3.0.0版本——Broker(Zookeeper服务端存储的Kafka相关信息)
目录 一、启动zookeeper集群及kafka集群服务启动1.1、先启动三台zookeeper集群服务,再启动三台kafka集群服务1.2、使用PrettyZoo连接zookeeper客户端工具 二、在zookeeper服务端存储的Kafka相关信息 一、启动zookeeper集群及kafka集群服务启动 1.1、先启动三台zook…...

【图论】无向图连通性(tarjan算法)
割边:dfn[u]<low[v] 割点:dfn[u]<low[v] (若为根节点,要有两个v这样的点) 一.知识点: 1.连通: 在图论中,连通性是指一个无向图中的任意两个顶点之间存在路径。如果对于图中的任意两个顶点 u 和 v&…...

Docker安装
Docker实践 yum安装 YUM源可以使用官方YUM源、清华大学开源镜像站配置YUM源,也可以使用阿里云开源镜像站提供的YUM源,建议选择使用阿里云开源镜像站提供的YUM源,原因速度快。 地址: https://developer.aliyun.com/mirror/ 我们安装ce版 …...
06. 计数原理
6. 计数原理 6.1 分类加法计数原理与分步乘法计数原理 分类加法计数原理定义 完成一件事,有 n n n 类办法,在第1类办法中有 m 1 m_1 m1 种不同的方法,在第2类办法中有 m 2 m_2 m2 种不同的方法,…,在第 n n…...

计算机网络基础(静态路由,动态路由,公网IP,私网IP,NAT技术)
文章目录 一:静态路由和动态路由二:静态路由的配置路由信息的方式演示三:默认路由四:公网IP和私网IP和NAT技术的基本理解 一:静态路由和动态路由 在说静态路由和动态路由前,我们需要来了解一下࿰…...
CGAL 点云Alpha-Shape曲面重建算法
文章目录 一、简介二、相关参数三、实现代码四、实现效果参考资料一、简介 在数学上, a l p h a − s h a p e alpha-shape a...
Java 文件过滤器FileFilter | 按条件筛选文件
文章目录 一、概述1.1 何时会用到文件过滤器1.2 工作流程1.3 常用的接口和类1.4 文件过滤器的作用 二、按文件属性过滤2.1 按前缀或后缀过滤文件名2.2 按文件大小过滤 三、按文件内容过滤3.1 文本文件过滤器3.1.1 根据关键字过滤文件内容3.1.2 使用正则表达式过滤文件内容 3.2 …...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...