Appium + mitmProxy 实现APP接口稳定性测试

news2024/11/27 22:35:03

随着 App 用户量的不断增长,任何小的问题都可能放大成严重的线上事故,为了避免对App造成损害的任何可能性,我们必须从各个方面去思考 App 的稳定性建设,尽可能减少任何潜在的威胁。

1.背景介绍

为了保障 App 的稳定性,我们现在有 XMoney 智能遍历测试(崩溃、界面错乱、加载异常等)、UI 自动化(崩溃和业务逻辑验证)、Top1000 小程序遍历(崩溃和业务逻辑报错)、接口稳定性建设(崩溃和业务逻辑验证)。 今天要给大家介绍的是接口稳定性建设,就是在后端返回数据如果不可靠的情况下,App 是否依然可以稳定运行。

2.实现思路

方案一

Mock有专门的Mock平台, 崩溃有专门的崩溃监控平台, 我们只需要把Mock数据下发到手机,如果有崩溃,会被崩溃平台收集到,崩溃会由值班同学分发给研发。

  1. 将接口代理到Mock平台,Mock平台根据response 生成批量的Mock数据
  2. 通过Appium调用App到制定页面, 触发对应请求,请求到了Mock平台后,Mock平台随机下发Mock数据
  3. 重复打开指定页面, 直到遍历完Mock数据
  4. 崩溃平台进行崩溃分发(人工)

优点:

短时间内可以覆盖大量的mock数据。

缺点:

mock数据不可控。

方案二

方案一有太多的随机性,为了让下发的数据和下发数据后的结果能够对应, 我们为了控制下发的数据, 我们在方案一的基础上自建Mock server, 通过Appium脚本和Mock server的交互,控制下发数据。

经调研,Mock server 比较大众的方案就是采用[mitmproxy](https://github.com/mitmproxy/mitmproxy), [mitmproxy](https://github.com/mitmproxy/mitmproxy)可实现 python 脚本的注入, 通过 python 脚本可以拦截请求的 request 和 response 数据,然后篡改数据后返回。因为 mitmproxy 是一个shell工具, 无法直接和python脚本交互, 所以python脚本和mitproxy的交互方式采用的是.ini的形式,互相读取 .ini 文件中的内容来实现数据交互。

优点:

mock数据可控制,可以校验预期结果。

缺点:

需要准备mock数据, mock数据要经常维护。

2种方案我们都有应用,方案一较为简单,在集成测试阶段执行,我们不再展开介绍。 方案二稍微麻烦一些,回归测试阶段执行。以下将详细介绍下方案二如何实现。

3.代码设计

方案流程

代码示例

测试Case

通过Mock更新数据,测试小程序升级的逻辑 (因涉及代码较多,大家可通过完整系统查看)

测试小程序的同步升级和异步升级逻辑, 修改测试配置后,mitmproxy会监控对应的接口请求, 发现存在要修改数据的请求,则进行response修改后返回给手机端。 手机端验证是否升级成功。

步骤:

  1. 修改测试配置(通过ini文件和mitmproxy实现联动, mitmproxy会在每次触发接口请求时检测当前的测试配置文件)

  2. 打开手机app

  3. 打开某个小程序

  4. 验证是否升级成功 (示例为把官方小程序Demo升级成为携程小程序)

    """ @File : test_update.py @Author : YangTongGang @Desc : 小程序升级(同步更新、异步更新) """

    class TestUpdate(BaseTestCases): """检测小程序同步更新、异步更新 已适配(iOS & Android) """ def setUp(self) -> None: # super(TestUpdate, self).setUp() self.business.del_sf_app('智能小程序') if self.is_android: self.business.del_sf_mine_app('智能小程序')

    def __update_action(self, is_sync=True):
        # 把CTS升级成携程, 并修改max age = 0
        # 控制mitmproxy进行不同的测试
        if is_sync:
            test_type = TestType.TestMaxAgeZero
        else:
            test_type = TestType.TestSaveResponse
        self.changeTestType(test_type)
        protocol = CaseManager.official_demo_case().protocol
        self.business.open_swan(protocol)
        if is_sync:
            test_type = TestType.TestSyncUpdate
        else:
            test_type = TestType.TestAsyncUpdate
        self.changeTestType(test_type)
    
    def test_max_age_force_update(self):
        """测试小程序同步更新"""
        self.__update_action()
        self.business.open_app()
        protocol = CaseManager.official_demo_case().protocol
        if self.business.open_swan(protocol):
            self.assert_validate('汽车票')
    
    
    Mitmproxy 启动

通过shell脚本启动mitmproxy并加载 http_handle.py文件,加载的python文件通过重写response或者request来达到监控每次请求的request和response的能力。

每次收到测试任务时,测试任务都会有相应的配置, 如果发现需要启动代理服务,则会自动调用如下脚本,启动代理, 然后手动配置测试机代理到服务地址,或者把任务打到固定的测试机上。

#!/usr/bin/env bash
: '
@File   : start_ui_mock.sh
@Author : YangTongGang
@Desc   : 启动UI Mock服务
'

script_file=/CaseTester/HTTPRouter/http_router.py

path=$0
current_path=${path%/*}
current_path=${current_path%/*}
# 启动mock 数据服务
file=/SHELL/start_mock.sh
file_path=${current_path}${file}
chmod +x "${file_path}"
sh "${file_path}" ${script_file}

#!/usr/bin/env bash
: '
@File   : start_mock.sh
@Author : YangTongGang
@Desc   : 启动接口Mock服务
'

path=$0
file_path=$1
current_path=${path%/*}
current_path=${current_path%/*}
file_path=${current_path}'/..'${file_path}
echo "${file_path}"

local_ip=$(ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"|head -n 1)
echo '=========== 代理服务地址 ============'
echo 'Script:' "${file_path##*/}"
echo ''
echo "${local_ip}":8088
echo ''
echo '==================================='

# mitmdump -s "${file_path}" -p 8088  --flow-detail 0
status=$(mitmdump -s ${file_path} -p 8088  --flow-detail 0)
if [$? == 0]
then
    exit 0
fi

监控response

注册对应的接口处理模块,遇到对应的接口时执行对应的测试。

"""
@File   : http_router.py
@Author : YangTongGang
@Desc   : 请求中转站
"""

# 注册handle
HANDLES = [
    # Core更新请求
    UpdateCoreHandle,
    # APS拉包请求
    PkgAPSHandle,
    # PMS拉包请求
    PkgPMSHandle,
    # Update接口
    UpdateHandle,
    # 我的页面, 下拉二楼的静默更新个数
    GetPkgListHandle
]

def response(flow):
    """接口response"""
    url = flow.request.url
    path = urlparse.urlsplit(url)['path']

    proxy_mock_urls = []
    for handle in HANDLES:
        proxy_mock_urls.append(handle.identifier)

    test_type = get_proxy_test_type()

    if test_type == TestType.TestNone:
        return

    if path not in proxy_mock_urls:
        return

    response_dic = json.loads(flow.response.content)
    for handle in HANDLES:
        if handle.identifier in path:
            handler = handle(response_dic, test_type)
            response_dic = handler.package_dic
            flow.response.content = bytes(json.dumps(response_dic), encoding='utf8')
            return

4.机房设计简介 

为了方便理解整个业务设计,顺便把我们的机房设计也给大家简单介绍一下。任务执行一般都是通过流水线派发到指定机房的随机空闲手机,测试完成后直接返回测试报告,测试执行人无需关心中间过程,也无需维护各种脚本。脚本都在机房维护, 避免在本地Appium部署困难, 脚本更新不及时等问题。

5.结语 

因为实际使用过程中依然需要大量人工介入,收益较小,所以执行频率不高,且该方案时间略微久远,所以在此只给大家抛砖引玉,开拓下思路之用,后续如有需要可以作为一种备选方案。

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

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

相关文章

C#,码海拾贝(29)——求解“大型稀疏方程组”的“全选主元高斯-约去消去法”之C#源代码

大型稀疏矩阵线性化方程组的数值求解问题 广泛存在于工程实践尤其是计算机仿真领域 如水力管网计算,电力系统的大型导纳矩阵计算,高阶偏微分方程的数值求解,以及铸件充型过程与凝固过程的数值模拟等。 经常出现在科学和工程计算中, 因此寻找…

【spring源码系列-03】xml配置文件启动spring时refresh的前置工作

Spring源码系列整体栏目 内容链接地址【一】spring源码整体概述https://blog.csdn.net/zhenghuishengq/article/details/130940885【二】通过refresh方法剖析IOC的整体流程https://blog.csdn.net/zhenghuishengq/article/details/131003428【三】xml配置文件启动spring时refres…

【科技素养题】少儿编程 蓝桥杯青少组科技素养题真题及解析第19套

少儿编程 蓝桥杯青少组科技素养题真题及解析第19套 1、下列现象中有化学变化发生的是 A、蜡烛融化 B、冰块融化 C、电磁炉烧开水 D、铁生锈 答案:D 考点分析:主要考查小朋友们的物理和化学知识,题目问的是化学变化;区别物理变化和化学变化的唯一标志是有无新物质生成…

公司来了个新的测试员,本以为是个菜鸡,没想到......

最近公司来了个新同事,学历并不高,而且大学也不是计算机专业的,今年刚满30岁。。 本以为也是来干点基础的活混混日子的,结果没想到这个人上来就把现有项目的性能测试了一遍,直接给公司节省了不少成本,这种…

C语言/C++新手入门学习经验资料分享

一 学好C语言的运算符和运算顺序 这是学好《C程序设计》的基础,C语言的运算非常灵活,功能十分丰富,运算种类远多于其它程序设计语言。 在表达式方面较其它程序语言更为简洁,如自加、自减、逗号运算和三目运算使表达式更为简单&a…

硅谷最爱的测试框架:详解PyTest

Python中有许多测试框架,但其中最受欢迎的就是PyTest。PyTest是一个强大而灵活的测试框架,它提供了许多先进的功能,可以让你的测试更加简洁、易读。 一、PyTest 简介 PyTest是一个开源的Python测试框架,用于编写简单而丰富的测试…

FreeRTOS_任务基础知识

目录 1. 什么是多任务系统? 2. FreeRTOS 任务与协程 2.1 任务 (Task) 的特性 2.2 协程(Co - routine)的特性 3. 任务状态 4. 任务优先级 5. 任务实现 6. 任务控制块 7. 任务堆栈 RTOS 系统的核心就是任务管理,FreeRTOS 也…

软件测试想要高薪资,不仅要卷还要学会跳槽

都说00后躺平了,但是有一说一,该卷的还是卷。 这不,前段时间我们公司来了个00后,工作都没两年,跳槽到我们公司起薪20K,都快接近我了。后来才知道人家是个卷王,从早干到晚就差搬张床到工位睡觉了…

C++ new和delete的使用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、new和delete介绍二、简单使用1.new和delete2.自定义对象3.new[]和delete[]4.主存耗尽5.try&catch6.nothrow7.看下源代码 前言 new和delete是C里非常重…

【运维】服务器系统安装

目录 一、环境 二、ubuntu 三、启动u盘制作 Stage 1:下载balena,制作U盘启动工具 Stage 2:下载Ubuntu 系统镜像(参考上一节:Ubuntu 22.04.2 LTS ) Stage 3:将镜像写入到U盘 四、设置开启…

6 面阿里、5 面字节、4 面腾讯,可算是入坑了····

8 年前,BAT 冲到了风口浪尖,美国上市的阿里成为中国体量最大的互联网公司,腾讯借助微信成为移动互联网的霸主,外企开始撤离中国,国企的光环也慢慢褪去。 到了近年,应届毕业生心中最炙手可热的公司换成了 T…

共话出海、布局全球,融云WICC2023 · 泛娱乐出海嘉年华广州收官!

(移步公众号点击图片三折购买《社交泛娱乐出海作战地图》) 6 月 2 日,“WICC 泛娱乐出海嘉年华”在广州成功举办,圆满收官。关注【融云全球互联网通信云】了解更多 本届嘉年华由高端峰会、圆桌会议、露营派对三部分组成&#xf…

资深8年测试,全链路压测与性能的优化详解,一文通透...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 什么是全链路压测…

了解CPU瓶颈原因,掌握代码优化、TOP命令及缓存技术,让服务器不再为性能瓶颈所困扰。

目录 前言: 一、CPU瓶颈原因分析 1. CPU使用率过高 2. 进程使用CPU过多 3. 磁盘I/O读写速度过慢 二、CPU瓶颈调优方案 1. 使用top命令查看CPU使用率 2. 优化程序设计 3. 使用缓存技术 总结: 前言: 在服务器运行过程中,…

干货 | 实战演练基于加密接口测试测试用例设计

如果接口测试仅仅只是掌握一些requests或者其他一些功能强大的库的用法,是远远不够的,还需要具有根据公司的业务以及需求去定制化一个接口自动化测试框架能力。所以在这个部分,会主要介绍接口测试用例分析以及通用的流程封装是如何完成的。 首…

GitHub 竟然有这些骚操作,真是涨姿势

GitHub 竟然有这些骚操作,真是涨姿势 GitHub,不用过多介绍。一个面向开源及私有软件项目的托管平台,因为只支持 git 作为唯一的版本库格式进行托管,故名 GitHub。 作为「全球最大的程序员“交友”社区」,程序员的你&am…

入门AI从谷歌这10门独立课程开始

​ 谷歌最近发布了一个名为"Generative AI learning path"的学习路径,该路径专为初学者设计,共包含10门独立课程。通过这个学习路径,初学者可以从基础概念开始学习,并逐步深入到更复杂的主题,帮助他们了解生…

NLP实战:调用Gensim库训练Word2Vec模型

目录 一、准备工作 1. 安装Gensim库 2. 对原始语料分词 二、训练Word2Vec模型 三、模型应用 1.计算词汇相似度 ​编辑 2. 找出不匹配的词汇 3. 计算词汇的词频 四、总结 🍨 本文为[🔗365天深度学习训练营]内部限免文章(版权归 *K同学…

第7章:SpringMVC的HttpMessageConverter

1. HttpMessageConverter简介 ①HttpMessageConverter,报文信息转换器,将请求报文转换为java对象,或将java对象转换为响应报文 ②HttpMessageConverter提供了两个注解和两个类型 RequestBody,ResponseBody,RequestEntity,ResponseEntity …

深入详解CFS任务放置代码

一、前言 本文出现的内核代码来自Linux5.10.61,为了减少篇幅,我们对引用的代码进行了删减(例如去掉了NUMA的代码,毕竟手机平台上我们暂时不关注这个特性),如果有兴趣,读者可以配合完整的源代码…