【编写UI自动化测试集】Appium+Python+Unittest+HTMLRunner
简介
- 获取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()
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什
相关文章:

【编写UI自动化测试集】Appium+Python+Unittest+HTMLRunner
简介 获取AppPackage和AppActivity 定位UI控件的工具 脚本结构 PageObject分层管理 HTMLTestRunner生成测试报告 启动appium server服务 以python文件模式执行脚本生成测试报告 下载与安装 下载需要自动化测试的App并安装到手机 获取AppPackage和AppActivity 方法一 有源码的…...

大模型如何协助知识图谱进行实体关系之间的分析
大模型在知识图谱中协助进行实体关系分析的方式主要体现在以下几个方面: 增强数据标注与知识抽取 大模型通过强大的自然语言处理能力,能够高效地对原始数据进行实体、关系和事件的标注,从而提高数据处理的效率和准确性。例如,Deep…...

推荐几款优秀的PDF转电子画册的软件
当然可以!以下是几款优秀的PDF转电子画册的软件推荐,内容简洁易懂,这些软件都具有易用性和互动性,适合不同需求的用户使用。 ❶ FLBOOK|在线创作平台 支持PDF直接导入生成仿真翻页电子书。提供15主题模板与字体库&a…...

【大模型技术】LlamaFactory 的原理解析与应用
LlamaFactory 是一个基于 LLaMA 系列模型(如 LLaMA、LLaMA2、Vicuna 等)的开源框架,旨在帮助开发者和研究人员快速实现大语言模型(LLM, Large Language Model)的微调、推理和部署。它提供了一套完整的工具链࿰…...

Golang依赖注入实战:从容器管理到应用实践
#作者:曹付江 文章目录 1、示例: 管理依赖关系的容器1.1. 日志记录器设置1.2. 数据库连接设置1.3. 管理依赖关系的容器 2、如何使用容器3、结论 依赖注入(DI)是一种在软件应用程序中促进松散耦合和可测试性的设计模式。它允许将依…...

Node.js二:第一个Node.js应用
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 创建的时候我们需要用到VS code编写代码 我们先了解下 Node.js 应用是由哪几部分组成的: 1.引入 required 模块:我们可以使用 requi…...

【Python爬虫】利用代理IP爬取跨境电商AI选品分析
引言 随着DeepSeek的流行,越来越多的用户开始尝试将AI工具融入到日常工作当中,借助AI的强大功能提高工作效率。最近又掀起了一波企业出海的小高潮,那么如果是做跨境电商业务,怎么将AI融入工作流中呢?在做跨境电商的时候…...

生命周期总结(uni-app、vue2、vue3生命周期讲解)
一、vue2生命周期 Vue2 的生命周期钩子函数分为 4 个阶段:创建、挂载、更新、销毁。 1. 创建阶段 beforeCreate:实例初始化之后,数据观测和事件配置之前。 created:实例创建完成,数据观测和事件配置已完成,…...

计算机数据库三级刷题总结(博主89分已过,总结的内容分享)
计算机数据库三级刷题总结(博主89分已过,总结的内容分享) 文章目录 计算机数据库三级刷题总结(博主89分已过,总结的内容分享)一、 数据库设计阶段二、事务相关三、数据库设计顺序四、数据库三级模式与二层映…...

mfc140u.dll是什么?当程序遭遇mfc140u.dll问题:快速恢复正常的秘诀
在使用Windows操作系统运行某些软件时,不少用户会遇到令人头疼的mfc140u.dll文件丢失错误。mfc140u.dll这个错误一旦出现,往往导致相关程序无法正常启动或运行,给用户带来诸多不便。这天的这篇文章将给大家分析mfc140u.dll是什么?…...

AI是否能真正理解人类情感?从语音助手到情感机器人
引言:AI与情感的交集 在过去的几十年里,人工智能(AI)的发展速度令人惊叹,从简单的语音识别到如今的深度学习和情感计算,AI已经深入到我们生活的方方面面。尤其是在语音助手和情感机器人领域,AI不…...

3.3.2 Proteus第一个仿真图
文章目录 文章介绍0 效果图1 新建“点灯”项目2 添加元器件3 元器件布局接线4 补充 文章介绍 本文介绍:使用Proteus仿真软件画第一个仿真图 0 效果图 1 新建“点灯”项目 修改项目名称和路径,之后一直点“下一步”直到完成 2 添加元器件 点击元…...

JetBrains学生申请
目录 JetBrains学生免费授权申请 IDEA安装与使用 第一个JAVA代码 1.利用txt文件和cmd命令运行 2.使用IDEA新建项目 JetBrains学生免费授权申请 本教程采用学生校园邮箱申请,所以要先去自己的学校申请校园邮箱。 进入JetBrains官网 点击立即申请,然…...

深入探索WebGL:解锁网页3D图形的无限可能
深入探索WebGL:解锁网页3D图形的无限可能 引言 。WebGL,作为这一变革中的重要技术,正以其强大的功能和广泛的应用前景,吸引着越来越多的开发者和设计师的关注。本文将深入剖析WebGL的核心原理、关键技术、实践应用,并…...

SQL进阶技巧:上课时长计算
目录 0 问题描述 1 数据准备 2 问题解决 核心难点 时间区间标记与分组 区间合并与时长计算...

“沂路畅通”便利服务平台:赋能同城物流,构建高效畅通的货运生态
“沂路畅通”便利服务平台:赋能同城物流,构建高效畅通的货运生态 随着城市化进程的加速,同城物流需求迅速增长,然而货运过程中仍然存在信息不对称、资源浪费、司机服务体验差等痛点。临沂呆马区块链网络科技有限公司(…...

文件上传靶场(1--9关)
实验环境: 1,upload的靶场环境可以去GitHub上自行查找 2,打开小皮面板的nginx和数据库 3,将文件上传的靶场部署到本地: 放到小皮的phpstduy_pro的www下面 小提示: 另外如果你用的是php7的版本建议将版…...

嵌入式 ARM Linux 系统构成(1):Bootloader层
目录 一、Bootloader 概述 1.1 核心作用 1.2 典型启动流程 二、ARM Bootloader 架构详解 2.1 多阶段启动设计 2.2 关键代码流程 2.3. Bootloader的加载过程 2.4. Bootloader的加载方式 2.5. Bootloader 的移植 三、常见的Bootloader介绍 3.1. U-Boot 3.2. vivi …...

ArcGIS Pro 基于基站数据生成基站扇区地图
在当今数字化的时代,地理信息系统(GIS)在各个领域都发挥着至关重要的作用。 ArcGIS Pro作为一款功能强大的GIS软件,为用户提供了丰富的工具和功能,使得数据处理、地图制作和空间分析变得更加高效和便捷。 本文将为您…...

GaussianCity:实时生成城市级数字孪生基底的技术突破
在空间智能领域,如何高效、大规模地生成高质量的3D城市模型一直是一个重大挑战。传统方法如NeRF和3D高斯溅射技术(3D-GS)在效率和规模上存在显著瓶颈。GaussianCity通过创新性的技术方案,成功突破了这些限制,为城市级数字孪生的构建提供了全新路径。 一、核心创新:突破传…...

【个人学习总结】反悔贪心:反悔堆+反悔自动机
参考:【学习笔记】反悔贪心 - RioTian 什么是反悔贪心? 反悔贪心,就是可以回溯的贪心,一般题目我们能使用正常贪心的情况是很少的,因为我们只考虑了局部最优解,我们不能保证局部最优解是最后的最优解&…...

通往 AI 之路:Python 机器学习入门-线性代数
2.1 线性代数(机器学习的核心) 线性代数是机器学习的基础之一,许多核心算法都依赖矩阵运算。本章将介绍线性代数中的基本概念,包括标量、向量、矩阵、矩阵运算、特征值与特征向量,以及奇异值分解(SVD&…...

迷你世界脚本UI五子棋小游戏
wzq_jm "7477124677881080183-22855"--界面id wzq_jmjxh "7477124677881080183-22855_"--界面加下划线 wzq_tc "7477124677881080183-22855_262"--退出按钮id wzq_hdlt1 "7477124677881080183-22855_267"--互动聊天按钮 快点吧&a…...

阿里万相,正式开源
大家好,我是小悟。 阿里万相正式开源啦。这就像是AI界突然开启了一扇通往宝藏的大门,而且还是免费向所有人敞开的那种。 你想想看,在这个科技飞速发展的时代,AI就像是拥有神奇魔法的魔法师,不断地给我们带来各种意想…...

C# 数据转换
1. 文本框读取byte,ushort格式数据 byte addr; if (byte.TryParse(textBoxAddr.Text, out addr) true) {}2. 字节数组 (byte[]) 转换为 ASCII 字符串 byte[] bytes { 72, 101, 108, 108, 111 }; // "Hello" 的 ASCII 码 string s0 Encoding.ASCII.Ge…...

学习第十一天-树
一、树的基础概念 1. 定义 树是一种非线性数据结构,由 n 个有限节点组成层次关系集合。特点: 有且仅有一个根节点其余节点分为若干互不相交的子树节点间通过父子关系连接 2. 关键术语 术语定义节点包含数据和子节点引用的单元根节点树的起始节点&#…...

网络服务之SSH协议
一.SSH基础 1.1 什么是ssh SSH(Secure Shell)协议是一种用于字符界面远程登录和数据加密传输的协议。 1.2 ssh优点 优点: 数据传输是加密的,可以防止信息泄漏 数据传输是压缩的,可以提高传输速度 注意ÿ…...

蓝桥杯 之 前缀和与查分
文章目录 题目求和棋盘挖矿 前缀和有利于快速求解 区间的和、异或值 、乘积等情况差分是前缀和的反操作 前缀和 一维前缀和: # 原始的数组num,下标从1到n n len(num) pre [0]*(n1) for i in range(n):pre[i1] pre[i] num[i] # 如果需要求解num[l] 到num[r] 的区…...

GB28181开发--ZLMediaKit+WVP+Jessibuca
一、核心组件功能 1、ZLMediaKit 定位:基于 C++11 的高性能流媒体服务框架,支持 RTSP/RTMP/HLS/HTTP-FLV 等协议互转,具备低延迟(最低 100ms)、高并发(单机 10W 级连接)特性,适用于商用级流媒体服务器部署。 特性:跨平台(Linux/Windows/ARM 等)、支持 …...

Ubuntu20.04 在离线机器上安装 NVIDIA Container Toolkit
步骤 1.下载4个安装包 Index of /nvidia-docker/libnvidia-container/stable/ nvidia-container-toolkit-base_1.13.5-1_amd64.deb libnvidia-container1_1.13.5-1_amd64.deb libnvidia-container-tools_1.13.5-1_amd64.deb nvidia-container-toolkit_1.13.5-1_amd64.deb 步…...