PageObject+Python+Appium

目录

前言:

简介

功能

常用目录

配置

实例 - 第一次启动 app

实例 - 登录

代码入口实例

结果展示


前言:

Page Object模式是一种常用的设计模式,用于组织和管理自动化测试脚本中的页面对象。它将页面的元素和操作封装在一个独立的类中,使测试脚本更加模块化、可维护和可重用。

简介

  • 基于 appium+python3 封装的自动化测试框架

功能

  • python3
  • unittest 参数化
  • pageobject
  • 数据维护用的 YMAL
  • excel 的测试报告
  • 支持多设备 andoird 并行
  • 支持 webview

常用目录

  • Base 封装常用方法
  • Log 记录不同设备的操作用例的日志,操作失败的截图
  • PageObject 放 page
  • test 目录写测试用例
  • runner 运行入口

配置

配置 run.yaml

app: Jianshu.apk

配置 devices.yaml

- devices:  emulator-5554
  port: 4724
  config: appium --session-override  -p 4724 -bp 4734 -U  emulator-5554
  platformName: android
- devices: DU2TAN15AJ049163
  port: 4725
  config: appium --session-override  -p 4725 -bp 4735 -U  DU2TAN15AJ049163
  platformName: android

实例 - 第一次启动 app

配置用例 yaml

testinfo:
    - id: test001
      title: 第一次打开
testcase:
    - operate_type: swipeLeft
      time: 4
      element_info: android.widget.ImageView
      find_type: class_name
    - element_info: com.jianshu.haruki:id/tv_enter
      find_type: id
      operate_type: click
check:
    - element_info: com.jianshu.haruki:id/btn_login
      find_type: id

PageObject

class FirstOpen:
    '''
    kwargs: WebDriver driver, String path(yaml配置参数)
    isOperate: 操作失败,检查点就失败
    testInfo:
    testCase:
    '''

    def __init__(self, **kwargs):
        self.driver = kwargs["driver"]
        self.path = kwargs["path"]
        self.operateElement = OperateElement(self.driver)
        self.isOperate = True
        self.testInfo = getYam(self.path)["testinfo"]
        self.testCase = getYam(self.path)["testcase"]


    '''
    操作步骤
    logTest 日记记录器
    '''

    def operate(self, logTest):
        for item in self.testCase:
            result = self.operateElement.operate(item, self.testInfo, logTest)

            if not result:
                print("操作失败")
                self.isOperate = False
                break

    '''
    检查点
    caseName:函数名
    logTest 记录日志:一个手机记录单独记录一个日志
    '''

    def checkPoint(self, caseName, logTest, devices):
        result = False
        if not self.isOperate:
            print("操作失败,检查点失败")
            # return self.isOperate
        else:
            check = getYam(self.path)["check"]
            result = self.operateElement.findElement(check)  # 检查点

        countSum(result)
        countInfo(result=result, testInfo=self.testInfo, caseName=caseName, driver=self.driver, logTest=logTest, devices=devices)
        return result

test

PATH = lambda p: os.path.abspath(
    os.path.join(os.path.dirname(__file__), p)
)


class FirstOpenTest(ParametrizedTestCase):
    def testFirst(self):
        firsOpen = FirstOpen(driver=self.driver, path=PATH("../yaml/firstOpen.yaml"))
        firsOpen.operate(logTest=self.logTest)
        firsOpen.checkPoint(caseName=self.__class__.__name__, logTest=self.logTest, devices=self.devices["deviceName"])


    def setUp(self):
        super(FirstOpenTest, self).setUp()

实例 - 登录

配置 yaml

testinfo:
    - id: test0002
      title: 登录
testcase:
    - element_info: com.jianshu.haruki:id/btn_login
      find_type: id
      operate_type: click
    - element_info: com.jianshu.haruki:id/et_tel
      find_type: id
      operate_type: set_value
      text: username
    - element_info: com.jianshu.haruki:id/et_password
      find_type: id
      operate_type: set_value
      text: pwd
    - element_info: com.jianshu.haruki:id/btn_register_1
      find_type: id
      operate_type: click
    - element_info: //android.widget.ImageView[@index='0']
      find_type: xpath
      operate_type: click
check:
    - element_info: com.jianshu.haruki:id/add_subscribe
      find_type: id
    - element_info: com.jianshu.haruki:id/tab_more
      find_type: id

PageObject

class Login:
    '''
    kwargs: WebDriver driver, String path(yaml配置参数)
    isOperate: 操作失败,检查点就失败
    testInfo:
    testCase:
    '''

    def __init__(self, **kwargs):
        self.driver = kwargs["driver"]
        self.path = kwargs["path"]
        self.operateElement = OperateElement(self.driver)
        self.isOperate = True
        self.testInfo = getYam(self.path)["testinfo"]
        self.testCase = getYam(self.path)["testcase"]

    '''
    操作步骤
     logTest 日记记录器
    '''

    def operate(self, logTest):
        for item in self.testCase:
            result = self.operateElement.operate(item, self.testInfo, logTest)

            if not result:
                print("操作失败")
                self.isOperate = False
                break
    '''
    检查点
    caseName:测试用例函数名 用作统计
    logTest: 日志记录
    devices 设备名
    '''

    def checkPoint(self, caseName, logTest, devices):
        result = False
        if not self.isOperate:
            print("操作失败,检查点失败")
        else:
            check = getYam(self.path)["check"]
            result = self.operateElement.findElement(check)  # 检查点

        countSum(result)
        countInfo(result=result, testInfo=self.testInfo, caseName=caseName, driver=self.driver, logTest=logTest, devices=devices)
        return result

test

PATH = lambda p: os.path.abspath(
    os.path.join(os.path.dirname(__file__), p)
)


class LoginTest(ParametrizedTestCase):

    def testLogin(self):
        login = Login(driver=self.driver, path=PATH("../yaml/login.yaml"))
        login.operate(logTest=self.logTest)
        login.checkPoint(caseName=self.__class__.__name__, logTest=self.logTest, devices=self.devices["deviceName"])

    # def testWrongPwd(self):
    #     pass

    def setUp(self):
        super(LoginTest, self).setUp()

代码入口实例

def runnerCaseApp(devices):
    starttime = datetime.now()
    suite = unittest.TestSuite()
    suite.addTest(ParametrizedTestCase.parametrize(FirstOpenTest, param=devices)) # 引用不同的测试类
    suite.addTest(ParametrizedTestCase.parametrize(LoginTest, param=devices)) # 引用不同的测试类
    unittest.TextTestRunner(verbosity=2).run(suite)
    endtime = datetime.now()
    countDate(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), str((endtime - starttime).seconds) + "秒"

    ...


if __name__ == '__main__':
    if AndroidDebugBridge().attached_devices():
        getDevices = init()
        appium_server = AppiumServer(getDevices)
        appium_server.start_server()
        while not appium_server.is_runnnig():
            time.sleep(2)
        runnerPool(getDevices)
        appium_server.stop_server()
        writeExcel()
    else:
        print(u"设备不存在")

结果展示

日志目录

文件夹:samsung_GT-I9500_android_4.4,包含截图

2017-06-07 19:39:35,972  - INFO - ----  test001_第一次打开_android.widget.ImageView   START     ----
2017-06-07 19:39:44,433  - INFO - [CheckPoint_1]: FirstOpenTest: NG
2017-06-07 19:40:02,013  - INFO - ----  test0002_登录_com.jianshu.haruki:id/btn_login   START     ----
2017-06-07 19:40:03,075  - INFO - ----  test0002_登录_com.jianshu.haruki:id/et_tel   START     ----
2017-06-07 19:40:07,460  - INFO - ----  test0002_登录_com.jianshu.haruki:id/et_password   START     ----
2017-06-07 19:40:08,480  - INFO - ----  test0002_登录_com.jianshu.haruki:id/btn_register_1   START     ----
2017-06-07 19:40:13,640  - INFO - ----  test0002_登录_//android.widget.ImageView[@index='0']   START     ----

测试报告

  作为一位过来人也是希望大家少走一些弯路

在这里我给大家分享一些自动化测试前进之路的必须品,希望能对你带来帮助。

(软件测试相关资料,自动化测试相关资料,技术问题答疑等等)

相信能使你更好的进步!

点击下方小卡片

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

skbuff.h在哪

今天看来下底层socket的实现,发现很多人都说有个skbuff结构,我就想着去找下这个, cat /include/linux/skbuff.h 结果找不到,查了下,需要下载内核源码 //Ubuntusudo apt install linux-headers-genericdpkg -S skbuff.…

浏览器显示ERR_NETWORK_ACCESS_DENIED,安全设置或防火墙可能正在阻止连接,无法上网

环境: Win10 专业版 HP台式机 问题描述: 浏览器显示ERR_NETWORK_ACCESS_DENIED,安全设置或防火墙可能正在阻止连接,无法上网 1.无线连接状态正常 打不开网站 2.可以ping通百度DNS解析正常 3.防火墙已关闭 这样的错误可能由于多种原因而发生 原因分析 1.防火墙/防…

Unity游戏源码分享-Third Person Controller - Shooter Template v1.3.1

Unity游戏源码分享-Third Person Controller - Shooter Template v1.3.1 功能非常齐全 AI格斗 2.5D 完整工程地址:https://download.csdn.net/download/Highning0007/88057824

SpringCloud学习路线(3)—— Eureka注册中心

一、导引 服务调用出现的问题 服务调用采取的请求地址是静态的,当我们使用服务集群时,很容易造成只能调用固定的微服务上的接口。多个提供者,消费者的使用对象无法确定消费者无法得知提供者的状态 二、Eureka注册中心 (一&…

一个小技巧,分分钟搞定新零售!

新零售模式的兴起带来了线上线下销售渠道的整合,而自动售货机作为新零售模式的一种重要形式,提供了便捷的自助购物体验。 自动售货机作为新零售模式的一种典型应用,以其便利性、快捷性和24小时无人值守的特点,深受消费者和商家的青…

【C++】C++入门必备知识详细讲解

C入门必备知识 一、命名空间1. namespace2. namespace 的使用场景 二、了解 C 中的输入和输出三、缺省参数四、函数重载1. 函数重载的概念2. C支持函数重载的原理 五、引用1. 引用的概念2. 引用特性3. 常引用4. 引用的使用场景(1)做参数(传引…

ES系列--打分机制

一、文档打分机制 当你通过关键字搜索相关文档时,可能会出现多个文档,这些文档的顺序是通过一个max_score属性的大小从高到低顺序展现出来的,max_score属性就是我们所说的评分。而这个评分是通过一个文档打分机制计算出来的。 二、打分原理 …

第二章 Android 基础--开发基础

文章目录 1.使用真机调试运行2.Android开发涉及的编程语言3.工程目录结构4.编译配置文件 build.gradle5.清单文件6.界面显示与逻辑处理7.Activity创建与跳转8.练习题 本专栏主要在B站学习视频: B站Android视频链接 本视频范围:P9—P16 工程结构、设计规…

DDOS百科:什么是 DDoS 攻击及如何防护DDOS攻击

一、什么是 DDoS 攻击? 当多台机器一起攻击一个目标,通过大量互联网流量淹没目标或其周围基础设施,从而破坏目标服务器、服务或网络的正常流量时,就会发生分布式拒绝服务(DDoS)攻击。 DDoS允许向目标发送指数级更多的请求&#…

什么是 XSS 攻击,攻击原理是什么

什么是 XSS 攻击? XSS(Cross-Site Scripting)攻击是一种常见的 Web 安全漏洞,其攻击目标是 Web 应用程序中的用户,攻击者通过在 Web 页面中植入恶意脚本,从而实现窃取用户敏感信息、篡改用户数据等目的。 …

一本通12951917:装箱问题

不知道说什么废话好了 题目 装箱问题 描述 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品…

安卓进程间通信浅谈

Case: /Users/lucas/AndroidStudioProjects/aidldemo-master 一:操作系统 从操作系统原理去看,进程通信主要有三个方法:共享存储、消息传递、管道通信。 二:安卓中的IPC 进程间通信的几种方式:Intent(Bu…

华为产品测评官-开发者之声 - ModelArts 真实体验感想

华为产品测评官-开发者之声 - ModelArts 真实体验感想 我先是在6月17日参加了华为在深圳举办的开发者大会,后面看到群里发的"2023华为产品测评官-开发者之声"活动,简单看了一下体验活动的具体事情,感觉好玩…

超声医疗高压功率放大器ATA-4315技术参数

超声波检查或超声诊断,是一种非侵入性的医学检查方法,它利用了声波的高频振动来观察和评估人体内部的器官和组织。它基于不同密度和组织结构中传播的原理。通过将ultrasound(超声波)传递到身体的特定区域,并记录反射回来的声波,我…

flutter开发实战-svga播放svgaplayer_flutter直播礼物特效等效果使用

flutter开发实战-svga播放svgaplayer_flutter直播礼物特效等效果使用 最近开发过程中用到了SVGA进行播放动画,这里记录一下svgaplayer_flutter使用过程。svga可以做一些非常精美的动画,包括直播的刷礼物(火箭、跑车特效动画)等等。 效果图如下 一、SVG…

分区类型ID一键变身!快速改变分区类型ID的简单方法

分区类型ID是什么? 想要改变分区类型ID,先得明白分区类型ID是什么。大多数电脑用户可能只熟悉分区和分区类型,实际上有5种分区类型:主分区、可扩展固件接口(EFI)、扩展分区、逻辑分区和Microsoft保留分…

百分点科技苏萌受邀出席首届全国统计与数据科学联合会议

7月11-13日,首届全国统计与数据科学联合会议在北京举行,会议由中国现场统计研究会、中国数学会概率统计分 会、全国工业统计学教学研究会和中国商业统计学会联合主办,北京大学统计科学中心承办,旨在促进统计与数据科学领域发展&a…

vuecli5.x 配置图片输出为base64

解释:webpack的默认配置是小于一定的文件大小就要将图片转为base64, 所以尽量将这个阈值调大你的图片就可以转为base64; 当然这种做法不好, 会导致代码文件变大, 不过为了满足需求也没得办法。这年头大家都用 vite 了, 网上没有 vuecli5.x 这方面的记录, 写篇文章记…

Java经典面试解析:服务器卡顿、CPU飙升、接口负载剧增

01 线上服务器CPU飙升,如何定位到Java代码 解决这个问题的关键是要找到Java代码的位置。下面分享一下排查思路,以CentOS为例,总结为4步。 第1步,使用top命令找到占用CPU高的进程。 第2步,使用ps –mp命令找到进程下…

Flink 在新能源场站运维的应用

摘要:本文整理自中南电力设计院工程师、注册测绘师姚远,在 Flink Forward Asia 2022 行业案例专场的分享。本篇内容主要分为四个部分: 建设背景 技术架构 应用落地 后续及其他 点击查看原文视频 & 演讲PPT 一、建设背景 建设背景主要…