【UI自动化测试】appium+python+unittest+HTMLRunner

进阶Python接口自动化测试必备教程(2023全网最详细)

简介

  •  获取AppPackage和AppActivity
  •  定位UI控件的工具
  •  脚本结构
  •  PageObject分层管理
  •  HTMLTestRunner生成测试报告
  •  启动appium server服务
  •  以python文件模式执行脚本生成测试报告

下载与安装

下载需要自动化测试的App并安装到手机


获取AppPackage和AppActivity

参考:https://juejin.im/post/5c3809a451882524c84ebabe

最终,得到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环境里安装配置
(参考:https://blog.csdn.net/weixin_38981172/article/details/82389416)


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()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/2391.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

举例说明基于线性回归的单层神经网络网络(以梯度下降算法来求解权重的过程)...

我们将通过一个简单的例子来说明基于线性回归的单层神经网络,以及如何使用梯度下降算法来求解权重。 假设我们有以下数据集,表示学生的学习时间(小时)与他们的考试分数: 学习时间(X)&#xff1a…

线程池学习(五)线程工厂、线程池工厂

Executors 定义的Executor, ExecutorService, ScheduledExecutorService, ThreadFactory和Callable类的工厂和实用程序方法,我们称为线程池工厂。ThreadFactory 为定制化创建新线程的对象,我们称为线程工厂 前面几期的学习中,我已经初步会使用线程池了&…

MySQL内置函数

内置函数从实现的功能角度可以分为数值函数、字符串函数、日期和时间函数、流程控制函数、加密与解密函数,获取MySQL信息函数、聚合函数等。 1.数值函数 来源: 版权声明:本文为CSDN博主「清风拂来水波不兴」的原创文章,遵循CC 4…

Ceph简介及部署

Ceph Ceph一、存储基础1、单机存储设备2、Ceph 简介3、Ceph 优势5、Ceph 架构6、Ceph 核心组件7、OSD 存储后端8、Ceph 数据的存储过程9、Ceph 版本发行生命周期10、Ceph 集群部署 二、部署ceph-deploy Ceph 集群前环境配置1、关闭 selinux 与防火墙2、根据规划设置主机名3、配…

数据中心水浸事件,该如何找回安全?

数据中心是现代企业和组织中不可或缺的基础设施,承载着大量的敏感数据和关键业务运作。然而,水浸事件可能成为数据中心的巨大威胁,可能导致设备故障、数据丢失以及业务中断,给组织带来严重的损失和风险。 因此,为了保护…

gd32f103vbt6 串口OTA升级3-linux端的部分

一. 简介 本文主要是对linux端升级单片机程序的功能部分做一些介绍,包括一些软件流程。 二.硬件部分 2.1 rk3399cpugd32f103 2.2 连接方式:串口(115200,8N1)或者iic(本文没有介绍iic) 三、其…

WebRTC不同方案对比

1.功能上会有一些出入,尤其是国内的metaRTC版本迭代很快, 2.后续的ffmpeg也在进行支持webrtc特性,obs新的版本好像已经支持了webrtc, 3.对于webrtc部分缺少的信令部分的标准化也有了对应的标准whip和whep协议 所以,如…

一道SQL题

有个搞数仓的朋友不知道从哪儿弄了个题。。。 做了做体验了一下。。。 记录记录。 分析 要保证每天都要做新题 5天必须都做题,不然GG 最后一天必须做新题,如果最后一天做新题了,前面那几天没做新题,做的是老题 最后一天&#…

QT:问题、解决与原因

在这里记录一些自己遇到的在QT开发上面的小问题和tips 目录 QComboBox 设置qss样式不生效qt按钮设置点击释放效果实现效果 QComboBox 设置qss样式不生效 我设置的样式是: box->setStyleSheet("QComboBox {""border: none;""padding:…

支付宝支付上线准备工作(商家自研接入)

商家自研流程 1.创建应用 登录支付宝开放平台创建 网页/移动应用 说明:生成的应用唯一标识 APPID 可用于调用开放产品接口。 2.配置应用 2.1 应用详情 2.2 产品绑定 2.3 开发设置 在开发 > 开发设置 中配置应用信息。 2.3.1 接口加密方式 按操作步骤进行…

抖音seo源码部署/开源不加密可二开/抖音seo优化开发方案

一、前言 抖音是目前国内非常流行的短视频平台之一,用户数量庞大,更是吸引了许多企业和个人在上面开设账号,通过发布内容来进行流量变现。但是,在一个账号发布内容的同时,管理员又需要同时关注多个账号,对账…

mysql中的行格式之compact格式分析

mysql中的行格式之compact格式分析 mysql行格式 所谓行格式,就是指mysql一行数据的存储格式。 InnoDB 储存引擎支持有四种行储存格式:Compact、Redundant、Dynamic 和 Compressed。 Redundant是很古老的行格式了,因为占用空间最多&#x…

基于深度学习的高精度道路瑕疵检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要:基于深度学习的高精度道路瑕疵(裂纹(Crack)、检查井(Manhole)、网(Net)、裂纹块(Patch-Crack)、网块(Patch-Net)、坑洼块&#x…

【C++】模板进阶—非类型模板参数、模板特化及模板的分离编译

🚀 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。 🚁 个人主页:不 良 🔥 系列专栏:🛸C 🛹Linux 📕 学习格言:博观而约取&#xff0…

什么是云应用程序?

应用程序优先的云服务的日益普及导致应用程序与云服务的融合程度比以前更深。应用程序和云之间的运行时边界正在从虚拟机转移到容器和函数。集成边界正在从仅访问数据库和消息代理转向应用程序的机械部分混合并在云中运行的边界。在这个最终架构中,应用程序是“云绑…

pwm呼吸灯

文章目录 一、呼吸灯二、代码实现三、引脚分配 一、呼吸灯 呼吸灯是指灯光在微电脑的控制之下完成由亮到暗的逐渐变化,使用开发板上的四个led灯实现1s间隔的呼吸灯。 二、代码实现 c module pwm_led( input clk ,input rst_n ,output reg [3:0] led ); …

photoshop制作法线和凹凸贴图

做个选区 Ctrlj 法线贴图 生成凹凸贴图

Spring框架的创建和使用

目录 Spring框架概述 什么是Spring框架 什么是容器 什么是IoC容器 Spring的核心功能 IoC容器和普通程序开发的区别 DI Spring项目的创建和使用 Spring项目创建 创建一个maven项目 添加Spring框架支持 添加一个启动类 Spring项目的使用 存储Bean对象 获取并使用B…

应用级监控方案Spring Boot Admin

1.简介 Spring Boot Admin为项目常用的监控方式,可以动态的监控服务是否运行和运行的参数,如类的调用情况、流量等。其中分为server与client: server: 提供展示UI与监控服务。client:加入server,被监控的…

vue3,elementPlus和自己封装,点击 新增添加表单,删除表单,提交数据

ElementPlus下的form也有新增表单 如果你写H5等没找到合适的 自己也可以进行封装 实现3个代码讲解:1:ElementPlus的代码 2:自己书写的代码 3:自己把2的代码进行封装 1:ElementPlus的运行效果 点击提交 1:ElementPlus…