运用短信案例举例!Appium自动化测试该如何进行PO模式

news2025/1/21 0:54:43

目录

前言:

案例一:自动发送短信


前言:

Appium是一种广泛用于移动应用程序自动化测试的工具,可以支持iOS和Android系统。在测试App时,使用Page Object(PO)模式可以提高测试用例的可重用性和可维护性。

核心思想:通过对界面元素的封装减少冗余代码,同时在后期维护中,若元素位置发生变化,只需要调整页面封装的代码,提高测试用例的可维护性、可读性。

优点: 

  • 减少了冗余代码

  • 业务代码和测试代码被分开,降低耦合性

  • 维护成本低

缺点:

  • 结构复杂:基于流程做了模块化的拆分

案例一:自动发送短信

方法:Appium+PO模式+Pytest框架数据参数化

模块分布

  • base模块:前置代码和基本操作,base_driver.py对应打开driver,base_action.py对应元素定位、点击按钮和输入。

  • page模块:对应操作页面,考虑手指测试的过程需要用到多少个页面,就在page模块中创建多少个文件。page.py统一入口,有多少个页面,就写多少个函数,并创建对应的对象。

  • scripts模块:测试脚本。

  • pytest.ini:配置文件。

base_action.py:

from selenium.webdriver.support.wait import WebDriverWait
 
class BaseAction:
 
    def __init__(self, driver):
        self.driver = driver
 
    def find_element(self, location, timeout=10, poll=1):
        """
        :param location: 元素位置
        :param timeout: 设置10秒
        :param poll: 多少秒找一次
        :return:
        """
        location_by, location_value = location
        wait = WebDriverWait(self.driver, timeout, poll)
        return wait.until(lambda x: x.find_element(location_by, location_value))
 
    def find_elements(self, location, timeout=10, poll=1):
        location_by, location_value = location
        wait = WebDriverWait(self.driver, timeout, poll)
        return wait.until(lambda x: x.find_elements(location_by, location_value))
 
    def click(self, location):
        self.find_element(location).click()
 
    def input(self, location, text):
        self.find_element(location).send_keys(text)
base_driver.py

from appium import webdriver
 
def init_driver():
    desired_caps = dict()
    # 设备信息
    desired_caps["platformName"] = "Android"
    desired_caps["platformVersion"] = "5.1"
    desired_caps["deviceName"] = "192.168.56.101:5555"
    # app信息
    desired_caps["appPackage"] = "com.android.mms"
    desired_caps["appActivity"] = ".ui.ConversationList"
 
    return webdriver.Remote("http://127.0.0.1:4723/wd/hub",desired_caps)

message_list_page.py

from selenium.webdriver.common.by import By
 
from base.base_action import BaseAction
 
class MessageListPage(BaseAction):
    # 新建短信按钮
    new_message_button = By.ID, "com.android.mms:id/action_compose_new"
 
    def click_new_message(self):
        self.click(self.new_message_button)

new_message_page.py

from selenium.webdriver.common.by import By
 
from base.base_action import BaseAction
 
class NewMessagePage(BaseAction):
    # 接受者特征
    recipients_edit_text = By.ID, "com.android.mms:id/recipients_editor"
    # 内容特征
    content_edit_text = By.ID, "com.android.mms:id/embedded_text_editor"
    # 发送按钮
    send_button = By.XPATH, "//*[@content-desc='发送']"
 
    def input_recipients(self, text):
        self.input(self.recipients_edit_text, text)
 
    def input_content(self, text):
        self.input(self.content_edit_text, text)
 
    def click_send(self):
        self.click(self.send_button)

page.py

from page.message_list_page import MessageListPage
from page.new_message_page import NewMessagePage
 
class Page:
 
    def __init__(self, driver):
        self.driver = driver
 
    @property
    def message_list(self):
        return MessageListPage(self.driver)
 
    @property
    def new_message(self):
        return NewMessagePage(self.driver)
test_message.py
import time
import pytest
from base.base_driver import init_driver
from page.page import Page
  
class TestMessage:
 
    def setup(self):
        self.driver = init_driver()
        self.page = Page(self.driver)
 
    def teardown(self):
        time.sleep(3)
        self.driver.quit()
 
    @pytest.mark.parametrize(('phone', 'content'), [('18588888888', "HELLO"),('18577778888', "您好!")])
    def test_send_message(self, phone, content):
        # 主页-点击短信,新建短信
        self.page.message_list.click_new_message()
        # 新建短信-输入 接收人
        self.page.new_message.input_recipients(phone)
        # 新建短信-输入 内容
        self.page.new_message.input_content(content)
        # 新建短信-点击发送
        self.page.new_message.click_send()
 
if __name__ == '__main__':
    pytest.main([])

pytest.ini

[pytest]
# 添加命令行参数
addopts = -vs --html=report/report.html --reruns 0
# 文件搜索路径
testpaths = ./scripts
# 文件名称
python_files = test_*.py
# 类名称
python_classes = Test*
# 方法名称
python_functions = test_*

Readme

短信案例
 
需求:
在《短信》应用中,进入发送短信页面,在姓名和内容栏中,输入对应的数据,并点击发送。
包名界面名:com.android.mms/.ui.ConversationList
发送短信页面标识:resource-id,com.android.mms:id/action_compose_new
接收者标识:resource-id,com.android.mms:id/recipients_editor
内容标识:resource-id,com.android.mms:id/embedded_text_editor
发送按钮标识:content-desc,发送
 
数据:
[18588888888, HELLO]
[18577778888, 您好!]

运行test_message.py

 作为一位过来人也是希望大家少走一些弯路,希望能对你带来帮助。(WEB自动化测试、app自动化测试、接口自动化测试、持续集成、自动化测试开发、大厂面试真题、简历模板等等),相信能使你更好的进步!

留【自动化测试】即可:

 

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

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

相关文章

如何短时间内上手公众号的运营?选择工具很重要

现在网上都在讲如何运营微信公众号,讲有什么微信公众号技巧,这些都是需要用户话花较多的时间去尝试和理解,今天小编分享一个更简单高效运营公众号的方法!下面跟着小编的教程一起学习如何使用乔拓云公众号助手去运营自己的公众号吧…

Vue3 ElementPlus Dialog封装

引言 多个页面中需要录入用户数据(弹窗内容相同),重复写弹窗代码比较繁琐。因此封装一下组件,使用效果如下: 本例中模型较简单,记录下使用方法和原理 实现原理 参考VUE官方两个例子,基本父子件…

C++ 教程(02)---- 环境设置

本地环境设置 如果您想要设置 C 语言环境,您需要确保电脑上有以下两款可用的软件,文本编辑器和 C 编译器。 文本编辑器 这将用于输入您的程序。文本编辑器包括 Windows Notepad、OS Edit command、Brief、Epsilon、EMACS 和 vim/vi。 文本编辑器的名…

技术架构演进

架构演进 单机架构应用数据分离架构应用服务集群架构读写 主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构实际互联网架构 单机架构 单机架构: 用户访问量很少,没有对我们的性能、安全等提出很高的要求,而且系统架构简单&#x…

Pilota:为什么一个代码生成工具如此复杂丨GOTC Rust系列分享

对于一个 Rust RPC 框架来说,根据 IDL 做代码生成是为了让用户更方便地使用框架。而生成代码的质量以及周边能力都会对用户的开发体验有着非常非常直接的影响。 所以,字节跳动 CloudWeGo 开发了 Pilota 这样的一个框架,来为用户生成良好的代码…

Redis延时双删

1.为什么缓存和MySQL数据没有保持一致性? 数据一致性是什么意思,“一致性”包含如下情况: 若缓存中有数据,则缓存的数据值需要和DB值相同若缓存无数据,则DB值必须是最新值 不符合这两种情况的,都属于缓存…

【OJ比赛日历】快周末了,不来一场比赛吗? #06.10-06.16 #12场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…)比赛。本账号会推送最新的比赛消息,欢迎关注! 以下信息仅供参考,以比赛官网为准 目录 2023-06-10(周六) #4场比赛2023-06-11…

实验五 标准ACL的配置【网络安全】

实验五 标准ACL的配置【网络安全】 前言推荐实验五 标准ACL的配置问题方案步骤 最后 前言 2023-6-8 18:54:22 以下内容源自《【网络安全】》 仅供学习交流使用 推荐 配置标准ACL 实验五 标准ACL的配置 问题 络调通后,保证网络是通畅的。同时也很可能出现未经…

软件测试与打螺丝

单元测试中的FIRST代表下面五组英文单词对应的原则: FastIsolated / IndependentRepeatableSelf-validatingTimely / Thorough 软件开发中,往往会因为我们没有注意到的逻辑或难以理解的代码,而引进Bug来。 怎么尽早地发现Bug,…

【springCloud-2】Ribbon负载均衡

负载均衡,一般分为服务端负载均衡和客户端负载均衡。 服务端:如Nginx,F5等,请求到达服务器后进行负载均衡。 客户端:客户端获取到服务端的列表,自己经过一定的计算后选择某一台访问。 ribbon实现的就是客…

Monica: 您的又一个免费ChatGPT 4.0

最近 ChatGPT 又开始封号了,主要原因如下: 违反使用条款:如果用户违反了平台或应用的使用条款,例如发布违法、恶意或滥用行为的内容,侵犯他人的权利,或者从事垃圾信息传播等,管理员可能会采取封…

多方合作时,系统间的交互是怎么做的?

大家好!我是sum墨,一个一线的底层码农,平时喜欢研究和思考一些技术相关的问题并整理成文,限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。 以下是正文! 文章背景 我们最近做了很多…

【资料分享】ESD基本概念及ESD产生来源详解

CMOS工艺集成电路制造技术已经进入纳米时代,随着特征尺寸的降低,ESD (Electro-Static Discharge,静电放电)问题越来越成为集成电路中最主要的可靠性问题。 ESD基本概念 ESD定义:ESD(Electro-Static disc…

垄断与市场力量

五力竞争分析模型 供应商的判断能力购买者的判断能力新进入者的威胁现有的竞争对手产品和服务的替代品的压力产品和服务的互补品 政府决策价值定位 服务哪些客户?满足这些客户的哪些需求?收取什么价格?垄断企业的经营 竞争企业是价格接受者,而垄断企业是价格制定者。 市场…

PURE:A Frustratingly Easy Approach for Entity and Relation Extraction

原文链接: https://aclanthology.org/2021.naacl-main.5.pdf ACL 2021 介绍 对于命名实体识别和关系提取,最近的研究要么在这两个任务上使用一个预训练结构,要么通过共享表征来进行多任务学习。作者认为实体模型和关系模型在上下文表征中学到…

kotlin的abstract抽象类与interface接口建模按钮android点击事件处理

kotlin的abstract抽象类与interface接口建模按钮android点击事件处理 例如: abstract class View {private var listener: OnClickListener? nullprivate var enabled: Boolean falseconstructor() {println("view constructor")}fun setClickListen…

用法详解!postman接口自动化如何进行环境变量

目录 前言: 1.设置环境变量 2.设置全局变量 3.检查response body中是否包含某个string 4.检测JSON中的某个值是否等于预期的值 5.转换XML body为JSON对象 6.检查response body是否与某个string相等 7.测试response Headers中的某个元素是否存在(如:Content-…

自然语言处理: N-Gram实战

自然语言处理: 第一章N-Gram 一. 理论 定义: 语言模型在wiki的定义是统计式的语言模型是一个几率分布,给定一个长度为 m 的字词所组成的字串 W1 , W2 , ,Wn ,派几率的字符串P(S) P(W1 , W2 , ,Wn , )而其…

web audio音效播放器/音乐播放器

这是一个基于Web Audio API、HTML和CSS构建的高级网页音频播放器。它允许用户播放音频文件、控制播放、可视化音频,并应用音频效果和过滤器。 Github仓库: https://github.com/sonichen/Web-Based-Audio-Player 希望大家多多star 环境 操作系统&#…

Android逆向解析加壳与脱壳技术

加壳 加壳是指在 APK 文件中插入额外的代码或数据,使得原始代码难以被分析和反编译。通常加壳是为了保护软件的知识产权或者防止逆向工程。下面是 Android 加壳的一般流程: 选择加壳工具:选择合适的加壳工具进行加壳,比如市面上…